Do spisu tresci tematu 6

6.14.1 Funkcja Link()




Spis tresci


Wywolanie

int link(stara_sciezka, nowa_sciezka)
   char *stara_sciezka;    /* istniejacy plik
   char *nowa_sciezka;     /* nowa pozycja w katalogu

/* W przypadku powodzenia zwraca 0, bledu -1 */

Informacje ogolne

Funkcja systemowa link dodaje do katalogu nowe dowiazanie do pliku. Pierwszy parametr, stara_sciezka, okresla istniejace dowiazanie i sluzy do pobrania i-wezla danego pliku. Drugi parametr, nowa_sciezka tworzy nazwe nowego dowiazania. Oba dowiazania sa pod kazdym wzgledem identyczne.
Obowiazujacy identyfikator uzytkownika lub obowiazujacy identyfikator grupy musza zezwalac na wykonanie operacji pisania i wykonywania w katalogu w ktorym ma byc umieszczone nowe dowiazanie.
Dowiazanie okreslone przez drugi parametr funkcji nie moze istniec, funkcji link nie mozna uzyc do zmiany istniejacego dowiazania.
Dowiazanie do katalogu zezwala sie robic jedynie superurzytkownikowi (nadzorcy systemu)(oprocz . i ..). Ograniczenie to jest spowodowane tym, by nie byly tworzone dowiazania ktore powodowalyby tworzenie sie petli w drzewie katalogow. Zaklada sie, ze superurzytkownik nie bedzie takich dowiazan tworzyl.



Struktury danych


Wprowadzenie

Glowna struktura danych na ktorej dokonywane sa operacje dla funkcji link jest sturktura i-wezla (inode).


Struktura inode (przypomnienie)

Oto dokladna definicja struktury inode z pliku include/linux/fs.h:

struct inode {
	kdev_t		i_dev;
	unsigned long	i_ino;
	umode_t		i_mode;
	nlink_t		i_nlink;
	uid_t		i_uid;
	gid_t		i_gid;
	kdev_t		i_rdev;
	off_t		i_size;
	time_t		i_atime;
	time_t		i_mtime;
	time_t		i_ctime;
	unsigned long	i_blksize;
	unsigned long	i_blocks;
	unsigned long	i_version;
	unsigned long	i_nrpages;
	struct semaphore i_sem;
	struct inode_operations *i_op;
	struct super_block *i_sb;
	struct wait_queue *i_wait;
	struct file_lock *i_flock;
	struct vm_area_struct *i_mmap;
	struct page *i_pages;
	struct dquot *i_dquot[MAXQUOTAS];
	struct inode *i_next, *i_prev;
	struct inode *i_hash_next, *i_hash_prev;
	struct inode *i_bound_to, *i_bound_by;
	struct inode *i_mount;
	unsigned short i_count;
	unsigned short i_flags;
	unsigned char i_lock;
	unsigned char i_dirt;
	unsigned char i_pipe;
	unsigned char i_sock;
	unsigned char i_seek;
	unsigned char i_update;
	unsigned short i_writecount;
	union {
		struct pipe_inode_info pipe_i;
		struct minix_inode_info minix_i;
		struct ext_inode_info ext_i;
		struct ext2_inode_info ext2_i;
		struct hpfs_inode_info hpfs_i;
		struct msdos_inode_info msdos_i;
		struct umsdos_inode_info umsdos_i;
		struct iso_inode_info isofs_i;
		struct nfs_inode_info nfs_i;
		struct xiafs_inode_info xiafs_i;
		struct sysv_inode_info sysv_i;
		struct affs_inode_info affs_i;
		struct ufs_inode_info ufs_i;
		struct socket socket_i;
		void * generic_ip;
	} u;
};


Implementacja


Wprowadzenie

Kod zrodlowy tej funkcji znajduje sie w pliku linux/fs/namei.c, a czesc zalezaca bezposrednio od konkretnego systemu plikow w jednym z podkatalogow w katalogu lunux/fs. Opisany nizej algorytm opiera sie na systemie plikow ext2. I algorytm jest zdefiniowany w pliku linux/fs/ext2/namei.c.
Procedura sys_link (opisana ponizej) jest wykonywana w trybie jadra systemu.

Funkcja sys_link()

DEFINICJA: asmlinkage int sys_link(oldname, newname)
              const char *oldname;
              const char *newname;

    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
 Pobierz i-wezel pliku do ktorego bedzie robione dowiazanie;
 Kopiuj plik do wolnej przestrzeni adresowej jadra (getname());
 Wywolaj funkcje do_link();
 Zwolnij zarezerwowane strony przestrzeni jadra systemu;
}

Funkcja do_link()

DEFINICJA: int do_link(oldinode, newname)
              struct inode *oldinode;
              const char *newname;

    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
 Zwroc i-wezel katalogu dla danej nazwy pliku i nazwe 
    z katalogiem (dir_namei);
 Sprawdz czy katalog nie jest przeznaczony tylko do odczytu (IS_RDONLY);
 Sprawdz zgodnosc urzadzen (urzadzenia obu katalogow musza byc te same);
 Sprawdz czy jest prawo pisania(MAY_WRITE) i wykonywania(MAY_EXEC) w
    katalogu docelowym;
 Sprawdz czy mozna modyfikowac i-wezel do ktorego robimy dowiazanie (IS_APPEND)
    lub czy nie jest modyfikowany(IS_IMMUTABLE;
 Sprawdz czy w i-wezle jest zdefiniowane polecenie link;
 Zablokuj katalog macierzysty (down(&dir->i_sem));
 Wywolaj funkcje charakterystyczna dla danego systemu plikow (w naszym
    przypadku ext2_link);
 Odblokuj katalog macierzysty (up(&dir->i_sem));
 Zwolnij i-wezel katalogu macierzystego;
}

Funkcja ext2_link()

DEFINICJA: int ext2_link(oldinode, dir, name, len)
              struct inode *oldinode;
              struct inode *dir;
              const char *name;
              int len;
 
    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
 Sprawdz jezeli katalog, prawa do tworzenia dowiazania;
 Sprawdz czy i-wezel do ktorego robimy dowiazania mozna 
    modyfikowac(IS_APPEND) lub czy nie jest modyfikowany(IS_IMMUTABLE);
 Sprawdz czy liczba dowiazan nie przekroczyla maksymalnej ilosci
    (EXT2_LINK_MAX);
 Szukaj nazwy pliku wynikowego jezeli znaleziony zwroc 
    blad(ext2_find_entry);
 Dodaj plik do danego katalogu (ext2_add_entry);
 Ustaw wskaznik do i-wezla w nowym pliku;
 Dodaj informacje do katalogu o nowym pliku;
 Zaznacz, ze plik jest urzywany;
 Zapisz informacje z bufora i czekaj na zakonczenie operacji;
 Zwolnij bufor;
 Zwolnij i-wezel katalogu macierzystego;
 Zmien w starym i-wezle informacje o ilosci dowiazan
    i czasie ostatniej modyfikacji;
 Zwolnij i-wezel starego pliku;
}


Bibliografia

  1. Pliki zrodlowe Linuxa:
  2. Bach J.M., Budowa systemu operacyjnego Unix
  3. Rochkind M.J., Programowanie w systemie Unix dla zaawansowanych


Pytania i odpowiedzi

Prosze kierowac pytania pod moim adresem dotyczace danego tematu na ktore postaram sie odpowiedziec. Odpowiedzi prosze szukac wlasnie w tym miejscu.


Autor: Piotr Kawczynski