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 (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;
}
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: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 kolejki PIPE_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)
{
wykonaj put_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.