iget
znajdujacy sie w pliku
inode.c.
__iget()
DEFINICJA: struct inode* __iget(struct super_block *sb, int nr, int crossmntp) WYNIK: kopia z pamieci i-wezla o numerze nr z urzadzenia o super bloku sb w przypadku sukcesu, wpp. NULL (tylko gdy nie da sie pobrac i-wezla z listy wolnych)I-wezel identyfikowany jest przez numer urzadzenia, do ktorego nalezy (podane jako super blok) oraz przez swoj numer w tablicy i-wezlow tego urzadzenia. Stad argumenty wywolania funkcji
__iget
jednoznacznie wskazuja
i-wezel, ktorego kopie proces chce uzyskac. W przypadku, gdy istnieja powody,
dla ktorych proces musi czekac na ten i-wezel - jest usypiany.
Implementacja funkcji:
{ static struct wait_queue * update_wait = NULL; /* STATIC !!! */ struct inode_hash_entry * h; /* lista w tablicy mieszajacej */ struct inode * inode; /* zwracany i-wezel */ struct inode * empty = NULL; /* pobrany z listy wolnych */ Znajdz odpowiednia liste mieszajaca h; repeat: Szukaj w h i-wezla odpowiadajacego opisowi, jezeli znajdziesz, skocz do found_it; Jezeli nie ma przydzielonego wolnego i-wezla (empty==NULL) { Zwieksz licznik updating w h, zeby zaznaczyc ze chcemy cos namieszac w kolejce mieszajacej i zeby nikt niczego nie popsul; Pobierz wolny i-wezel (empty=get_empty_inode()); Zmniejsz licznik updating w h, bo juz nie bedziemy zmieniac wskaznikow, jezeli osiagnal on wartosc 0 (nikt juz nie miesza w kolejce) obudz wszystkie procesy z kolejki update_wait, zauwazmy, iz jest ona static; Jezeli jest ustalony wolny i-wezel (empty!=NULL) skocz do repeat wpp zwroc NULL; } Ustaw zwracany i-wezel na wolny (inode=empty); Ustaw jego parametry takie jak dev, sb, nr itp.; Przesun inode z kolejki wolnych przed nia (Aby wgrac z dysku i-wezel, jadro musi wyliczyc jego fizyczne polozenie na dysku (urzadzeniu logicznym). Poniewaz tablica i-wezlow jest przechowywana w pewnej ilosci blokow dyskowych, jadro musi znalezc blok, w ktorym znajduje sie i-wezel oraz jego numer w danym bloku (liczac od 0). Odbywa sie to w przyblizeniu wg nastepujacych wzorow:put_last_free(inode)
); Wstaw inode do kolejki mieszajacej; Wgraj i-wezel z dysku (read_inode
). Skocz do return_it; found_it: /* tutaj wszystkie operacje odwoluja sie do znalezionego inode */ Jezeli liczba otwarc pliku(i_count) jest 0, zmniejsz licznik wolnych i-wezlow (nr_free_inodes), bo znalezlismy w liscie wolny i-wezel; Zwieksz licznik otwarc(i_count++); Wykonaj test na blokade i-wezla(wait_on_inode(inode)
); Jezeli ustawienia sb i nr inode nie sa zgodne z szukanymi { zwolnij i-wezel(iput(inode)
) skocz do repeat; } Specjalne przetwarzanie w razie punktu zamontowania; Jezeli przetrzymywany wolny i-wezel zwolnij go (iput(empty)), bo masz inny z kolejki mieszajacej; return_it: Dopoki ktos cos zmienia w kolejce mieszajacej (h->updating>0) zasypiaj na kolejce update_wait; Zwroc inode; }
nr_bloku=((nr-1) div (i_per_block)) + nr_bloku_tablicy_iwezlow nr_iwezla=(nr-1) mod (i_per_block))Wystarczy teraz pomozyc nr_iwezla przez rozmiar struktury ext2_inode, aby uzyskac numer bajtu od ktorego nalezy rozpoczac czytanie i-wezla. Oczywiscie w systemie EXT2 nalezy do ww. wzorow wlaczyc informacje o grupach.
iput
, znajdujaca sie w pliku inode.c.
iput()
DEFINICJA: void iput(struct inode *inode) WYNIK: brak
Implementacja funkcji:
{ Wykonaj test blokady (wait_on_inode(inode)
); Jezeli licznik otwarc(i_count) = 0 wyjdz; Jezeli inode jest typu PIPE, obudz wszystkie przerywalne procesy z kolejkiPIPE_WAIT(*inode)
; repeat: Jezeli licznik otwarc jest > 1 to zmniejsz go o 1 i wyjdz; Zwolnij procesy czekajace na wolny i-wezel w kolejce inode_wait; Jezeli inode byl typu PIPE, zwolnij zwiazana z nim strone pamieci; Jezeli wszystkie wskazniki w inode sa OK(w tym na sb i funkcje) { wykonajput_inode(inode)
; jezeli liczba dowiazan do pliku wynosi 0, wyjdz; } Jezeli i-wezel nalezy zaktualizowac (i_dirt>0) { nagraj i-wezel (write_inode(inode)
); wykonaj test na blokade (wait_on_inode(inode)
); skocz do repeat; } Jezeli i-wezel ma charakter nagrywalny(plik,katalog lub link) i sa zdefiniowane operacje na quota { zaloz blokade na inode; uaktualnij quote(sb->dq->drop(inode)
); zdejmij blokade, a nastepnie skocz do repeat; } Zmniejsz licznik otwarc pliku (i_count); Zwieksz licznik wolnych i-wezlow (nr_free_inodes); }
get_empty_inode()
ustawia rozmaite parametry i-wezla (np. daje mu kolejny numer,
licznik wcielen 1, liczbe linkow 1 itp.), zmniejsza licznik wolnych i-wezlow
(UWAGA: Jezeli<0 to =0) i zwraca i-wezel.