Do spisu tresci tematu Pliki
6.6.3 Funkcja namei() - zamiana nazwy ścieżkowej na i-węzeł
Spis treści
Wstęp
Dostęp do plików poprzez wywoływanie funkcji systemowych realizowany
jest przez nazwy ścieżkowe, natomiast jądro wewnętrznie posługuje się
i-węzłami. W związku z tym konieczne jest dokonywanie konwersji z nazwy
ścieżkowej na odpowiadający jej i-węzeł. Konwersję tą dokonuje funkcja namei.
Nazwa ścieżkowa zbudowana jest z nazw katalogów oddzielonych znakami "/".
Nazwa może się zaczynać od "/" - wtedy jest to ścieżka bezwzględna
(od korzenia systemu plików) lub od innego znaku - wtedy jest to ścieżka względna
(od bieżącego katalogu).
Poza główną funkcją namei istnieją również jej odmiany używane przez konkretne
funkcje systemowe np. open. Zostaną one omówione w celu ukazania sposobów korzystania z
algorytmu namei().
Dwie specjalne funkcje lookup() i follow_link() implementują obsługę specjalnych
przypadków - przekraczanie punktów zamontowania plików i dowiązań symbolicznych. Jedynie w
tych dwóch funkcjach są realizowane zależne od systemu plików operacje na podstawie pola i_op w
i-węźle którego dotyczą, dzięki temu możliwe jest przejście przy punkcie montowania od
jednego systemu plików do drugiego.
Schemat algorytmu namei()
- 0. Algorytm namei posługuje się roboczym i-wezłem. Początkowo jest nim i-węzeł korzenia
drzewa katalogów (gdy nazwa ścieżkowa zaczyna się od znaku "/") lub aktualnego
katalogu (gdy zaczyna się od innego znaku). Zarówno korzeń drzewa jak i katalog roboczy są
pamiętane w u-obszarze procesu, ponieważ proces może zmienić swój korzeń drzewa (chroot) i
katalog roboczy (chdir)
- 1. Przeszukiwany jest plik opisany i-węzłem roboczym, (o ile jest on katalogiem - w
przeciwnym razie zwracany jest błąd)
- 2. Jeżeli nie znajdziemy w nim poszukiwanej pozycji (kolejnej nazwy podkatalogu, lub
pliku oddzielonej w ścieżce znakami "/") zwracamy błąd
- 3. Odczytujemy i-węzeł odpowiadający poszukiwanej pozycji i, po zwolnieniu roboczego i-węzła,
przypisujemy mu odczytany i-węzeł
- 4. Ewentualnie przechodzimy przez punkt montowania systemu plików lub dowiązanie symboliczne
- 5. Jeżeli nazwa ścieżkowa nie jest cała przetworzona - algorytm wraca do punktu 1.
Podzial algorytmu na funkcje pomocnicze w pliku źródłowym
Przybliżymy teraz zawartość pliku źródłowego - z wydzieleniem odpowiednich
funkcji pomocniczych używanych przez namei().
ext2_lookup()
DEKLARACJA:
int lookup(struct inode * dir,const char * name, int len,
struct inode ** result)
PARAMETRY:
dir - przeglądany katalog
name - poszukiwana nazwa
len - jej długość
result - wynikowy i-węzeł
WYNIK:
kod błędu gdy niepowodzenie
0 - gdy OK, wtedy wynikowy i-węzeł w zmiennej result
OPIS:
w pliku-katalogu opisanym przez i-węzeł dir poszukuje wpisu z nazwą name,
zwraca odpowiadający tej nazwie i-węzeł (plik lub katalog)
nazwa jest szukana najpierw w buforze z nazwami pozycji katalogowych,
dopiero potem ewentualnie (wrazie nie znalezienia) szukana na dysku
po odczytaniu z dysku pozycja jest dodawana do bufora z nazwami pozycji
UŻYWA: dcache_lookup(), dcache_add(), ext2_find_entry()
lookup()
DEKLARACJA:
int lookup(struct inode * dir,const char * name, int len,
struct inode ** result)
PARAMETRY:
dir - przeglądany katalog
name - poszukiwana nazwa
len - jej długość
result - wynikowy i-węzeł
WYNIK:
kod błędu gdy niepowodzenie
0 - gdy OK, wtedy wynikowy i-węzeł w zmiennej result
OPIS:
w pliku-katalogu opisanym przez i-węzeł dir poszukuje wpisu z nazwą name,
zwraca odpowiadający tej nazwie i-węzeł (plik lub katalog)
realizuje przechodzenie przez punkt zamontowania, dzieki porównaniu
dir z informacją o zamontowanym drzewie w superbloku
UWAGA:
Używa funkcji zależnych od systemu plików (poprzez dir->i_op->lookup())
W naszym przypadku - ext2_lookup()
follow_link()
DEKLARACJA:
int follow_link(struct inode * dir, struct inode * inode,
int flag, int mode, struct inode ** res_inode)
PARAMETRY:
dir - i-węzeł przeglądanego katalogu
inode - i-węzeł który może być dowiązaniem symbolicznym
flag, mode - ???
res_inode - wynikowy i-węzeł
WYNIK:
kod błędu gdy niepowodzienie
0 - gdy OK, wtedy wynikowy i-węzeł w zmiennej res_inode
OPIS:
Wywołuje funkcję zależną od systemu operacyjnego (poprzez inode->i_op->follow_link())
Pętle w dowiązeniach są wykrywane przez pięciokrotne przechodzenie przez dowiązania
dir_namei()
DEKLARACJA:
static int dir_namei(const char *pathname, int *namelen,
const char **name, struct inode * base, struct inode **res_inode)
PARAMETRY:
pathname - nazwa ścieżki do zamiany na i-węzeł
namelen - wskaźnik do zmiennej przechowującej długość wynikowej nazwy
name - wskaźnik do bufora na zwracaną nazwę
base - wskaźnik do bazowego i-węzła
res_inode - wskaźnik do zmiennej przechowującej zwracany i-węzeł (wł. wskaźnik)
WYNIK:
kod błędu, gdy niepowodzenie,
0 gdy OK, wtedy w odpowiednich zmiennych zwracane są i-węzeł i nazwa
OPIS:
zwraca i-węzeł katalogu o podanej nazwie ścieżkowej (pathname) i ostatnią
nazwę w nazwie ścieżkowej
czyli dla: "/abb/bba/cdef" zwraca i-węzeł katalogu "/abb/bba" i "cdef" jako nazwę
UŻYWA:
lookup(), followlink()
_namei()
DEKLARACJA:
static int _namei(const char * pathname, struct inode * base,
int follow_links, struct inode ** res_inode)
PARAMETRY:
pathname, base, res_inode - jak wyżej
follow_links - gdy !0 to wykonuje follow_link na ostatnim i-węźle
WYNIK:
kod błędu, gdy niepowodzenie,
0 gdy OK, wtedy w *res_inode zwracany jest i-węzeł (wł. wskaźnik)
OPIS:
zwraca i-węzeł odpowiadający plikowi o odpowiedniej nazwie ścieżkowej
używa dir_namei do zwrócenia i-węzła do katalogu, następnie lookup do
odczytania odpowiedniego wpisu w tym katalogu i ewentualnie, gdy
follow_links != 0, to wykonuje na nim follow_link
UŻYWA:
dir_namei(), follow_link(), lookup()
namei()
DEKLARACJA:
int namei(const char *pathname, struct inode **res_inode)
PARAMETRY:
pathname i res_inode jak wyżej
WYNIK:
jak wyżej
OPIS:
kopiuje nazwę z przestrzeni użytkownika do jądra wywołuje
_namei z parametrem follow_links = 1 zwalnia skopiowaną nazwę
zwraca wynik
UŻYWA:
_namei()
Sposoby wykorzystania algorytmu namei()
Sam algorytm namei() jest wykorzystywany tylko przez niektóre funkcje systemowe - te w najprostszy sposób
korzystające z przekształcania nazw ścieżkowych w i-węzły (np. chmod). Bardziej zaawansowane funkcje
np. do otwierania pliku, obsługi katalogów (rename, mkdir, rmdir itp.) wykorzystują dir_namei(), która
zwraca i-węzeł katalogu i nazwę pliku w tym katalogu. Można potem zmodyfikować wpis w pliku identyfikowanym zwróconym
i-węzłem na pozycji odpowiadającej zwróconej nazwie. Funkcja open() korzysta z rozbudowanej wersji namei(),
która jest oddzielną funkcją open_namei(). W niej właśnie dokonują się
sprawdzenia, czy plik o który chodzi może być czytany, czy musi zostać utworzony, a może jest gniazdem i
nie jest przechowywany na dysku (open_namei() korzysta również z dir_namei()).
Bibliografia
Autor: Paweł Mielańczuk