Skip to content


U*IX i jego system plików (cz.1)

Strukturą opisującą plik w U*IX’ie jest jego i-węzeł (i-node). Zawiera m.in. takie informacje jak rozmiar pliku, jego atrybuty, początek łańcucha sektorów, w którym są przechowywane dane pliku. Pewna (zadana z góry) liczba takich struktur jest tworzona na początku urządzenia pamięci masowej podczas tworzenia filesystemu. Zostają one ponumerowane po kolei i nadany w ten sposób numer i-węzła staje się jedynym identyfikatorem pliku w filesystemie (w systemie jest to unikalna para: plik urządzenia (i-węzeł) + i-węzeł pliku na urządzeniu). Jak można zauważyć, ogranicza to liczbę plików możliwą do stworzenia na urządzeniu. Może być ich dokładnie tyle, ile jest i-węzłów.

Reszta miejsca na urządzeniu zostaje zorganizowana w jeden, długi łańcuch połączonych ze sobą wolnych sektorów. Kiedy dane zostają zapisywane do pliku i występuje konieczność zwiększenia jego rozmiaru, od łańcucha wolnych sektorów zostaje odczepiony wolny sektor i przyczepia się go do łańcucha sektorów pliku. Kiedy plik jest usuwany, łańcuch jego sektorów zostaje doczepiony z powrotem do łańcucha sektorów wolnych.

Pliki najczęściej organizowane są w hierarchiczną strukturę drzewiastą za pomocą tzw. katalogów. Katalog jest plikiem, którego jedyną zawartość stanowi lista nazw, oraz przypisanych im numerów i-węzłów plików. Oczywiście na tej liście mogą występować wskazania na pliki będące również katalogami – są to tzw. podkatalogi. Poszukiwania liścia w drzewie hierarchicznym rozpoczyna się od korzenia. W systemie plików takim korzeniem jest pierwszy katalog – katalog „root” oznaczany /. Najczęściej umieszczany po prostu w pierwszym pliku (pierwszym i-węźle).

Uważny czytelnik zauważył już, że nazwa pliku nie jest przechowywana w jego i-węźle. Nazwa jest lokalną właściwością dla katalogu. Jedynym prawdziwym identyfikatorem pliku jest, jak już pisałem, numer jego i-węzła. Katalog zawiera nazwy, które są swego rodzaju wskaźnikami na i-węzły plików.
Podłączanie pliku (dowiązywanie) pod określoną nazwą w katalogu odbywa się za pomocą wywołania link(), a odłączanie za pomocą unlink().

Czy można więc dowiązać plik jednocześnie w wielu katalogach? Można. Co więcej, robi się to często i jest to bardzo przydatne (jeden program może występować pod wieloma nazwami i zachowywać się inaczej w zależności pod jaką nazwą został wywołany).

Co jednak z odwiązywaniem? Skąd system będzie wiedział, czy przy odwiązywaniu ma zwolnić i-węzeł pliku i jego sektory, czy jest on jeszcze gdzieś dowiązany i używany? Otóż w i-węźle pliku jest przechowywany licznik jego dowiązań. Licznik ten jest inkrementowany przy każdym dowiązywaniu, a dekrementowany przy odwiązywaniu. Jeśli osiągnie zero, oznacza to że plik należy usunąć. (Przy okazji – wyszukiwanie wolnego i-węzła do wykorzystania przy tworzeniu pliku, sprowadza się do znalezienia pierwszego i-węzła, którego licznik dowiązań jest równy zero.)

Przy takiej organizacji struktury katalogów przenoszenie plików z miejsca na miejsce sprowadza się do trywialnego link() w nowym miejscu, oraz unlink() w starym. (Dlaczego nie można tego zrobić w odwrotnej kolejności?)

Przykład z życia:

$ ls -li /usr/bin/
[...]
3955805 -r-xr-xr-x 2 root   root      11956 sty  8 13:33 skill
3955805 -r-xr-xr-x 2 root   root      11956 sty  8 13:33 snice

Pierwsza kolumna to numer i-węzła pliku. Jak widzimy pliki skill i snice to jeden plik, pod dwoma nazwami. Może to sugerować ten sam rozmiar i data ostatniej modyfikacji (również przechowywana w i-węźle), ale prawdziwy dowód to właśnie numer i-węzła.
Trzecia kolumna pokazuję liczbę dowiązań do pliku. Jak widać widzimy jedyne dwa dowiązania tego pliku.

Prześledźmy teraz pewien typowy scenariusz pracy z hierarchicznym systemem plików. Zaczynamy od katalogu /, którego numer i-węzła znamy. Ustawiamy sobie wskaźnik aktualnego położenia (cwd – Current Working Directory) na numer tego i-węzła i otwieramy plik o numerze przechowywanym w cwd. Przeglądamy plik w poszukiwaniu interesującego nas podkatalogu, a następnie odnaleziony numer i-węzła przypisany interesującej nas nazwie kopiujemy do cwd. Następnie otwieramy plik o numerze przechowywanym w cwd i wyszukujemy kolejną interesującą nas pozycję hierarchii. W ten sposób prosto i szybko możemy się zagłębiać w strukturze katalogów.

Co jednak, gdybyśmy chcieli odwołać się do katalogu nadrzędnego? Cofnąć się w hierarchii? A co z katalogiem bieżącym? Tak, mamy jego numerek w cwd, ale my ludzie lubimy używać nazw, nie numerków. Do katalogów podrzędnych (podkatalogów) odwołujemy się za pomocą nazw, więc do nadrzędnych i aktualnego chcielibyśmy analogicznie. Poza tym w przypadku użycia numerka cwd nazwa „katalog bieżący” nie byłaby stała, tylko zmieniała się.

Z pomocą znów przychodzą dowiązania. Podczas tworzenia pustego katalogu zostają w nim automatycznie utworzone dwa podkatalogi dowiązujące: katalog nowoutworzony pod nazwą . (kropka), oraz katalog dla niego nadrzędny pod nazwą .. (dwie kropki). Przy pomocy tych nazw można odwołać się (wyświetlić zawartość, przejść) do katalogów aktualnego i nadrzędnego. Obejrzyjmy to:

~/test $ ls -lia
5972576 drwxr-xr-x  2 smoku users   48 mar 19 13:53 .
224805 drwxr-xr-x 94 smoku users 3928 mar 19 13:53 ..

Jak widzimy nowoutworzony katalog test o numerze i-node 5972576 ma od razu dwa dowiązania: od swojego katalogu nadrzędnego (pod nazwą “test”), oraz od samego siebie pod nazwą “.”. Jego katalog nadrzędny ma aż 94 dowiązania. Można z tego łatwo wywnioskować, że w katalogu domowym mam 92 podkatalogi (jedno dowiązanie od rodzica, jedno od samego siebie i po jednym od .. (dwie kropki) w każdym podkatalogu). Widzimy też, że data modyfikacji obu katalogów jest taka sama. Katalog test został ostatnio zmodyfikowany podczas wpisywania do niego . i .., a jego katalog nadrzędny w tym samym momencie podczas dopisywania nowej pozycji test.

W związku z tym, że system identyfikuje plik przez numer jego i-węzła, jego dowiązania (i ich nazwy), są w pewnym sensie niezależne od samego pliku i jego zawartości. Dzięki temu wszystkie operacje plikowe możemy wykonywać nawet na plikach otwartych (wielokrotnie otwartych, spod różnych nazw). Otawrty plik możemy przenieść, zmienić jego nazwę, a nawet usunąć. Fizyczne zwolnienie miejsca pliku (i utrata danych) nastąpi dopiero po zamknięciu ostatniego aplikacyjnego uchwytu do pliku. Można więc używać danych z plików których „już nie ma”.


Posted in HowTo.


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

You must be logged in to post a comment.