2. Atrybuty plików w NTFS

2.1. Informacje wstępne

Metainformacje o plikach w NTFS nazywamy/trzymamy w atrybutach. Ciekawe jest to, że zawartość pliku w NTFS-ie także jest jego atrybutem. Poza zmianą koncepcyjną i trochę prostszą abstrakcją ma to też pewne istotne konsekwencje - konkretnie plik może mieć kilka zawartości. Dokładniej omówimy to później. Wspominamliśmy, że informacje o plikach są trzymane w MFT. Tak istotnie jest, ale z powodu ograniczonego rozmiaru rekordu MFT nie wszystko się tam mieści. Część atrybutów mieszcząca się w MFT nazywana jest rezydentymi, a pozostałe nierezydentnymi. W szczególności, kiedy plik jest mały, jego zawartość będąca przecież atrybutem może się mieścić w MFT. Mamy więc szybki dostęp do małych (800B - 1KB) plików. Niektóre informacje - takie jak np. nazwa pliku, czy prawa dostępu - muszą być rezydentne, inne (jak wspomniana zawartość) nie.

2.2. Omówienie atrybutów

Poniżej znajduje się lista opisów typów atrybutów plików i katalogów w NTFS. Większość z nich została bardziej szczegółowo omówiona w dalszej części prezentacji:

  1. Standard_Information - zawiera takie informacje jak stemple czasowe, czy prawa dostępu - tutaj rozumiane jako rodzaj pliku - archwialny, ukryty itp. Ciekawe jest to, że stemple czasowe są aktualizowane na dysku w odstępach godzinnych, lub przy zamknięciu ostatniej instancji pliku. Służy to zmniejszeniu liczby operacji dyskowych. Ten atrybut jest zawsze rezydentny.

  2. Attribute_List - czasami zdarza się tak, że jeden rekord MFT jest zbyt mały, żeby zmieścić wszystkie atrybuty, które muszą znajdować się w MFT, a także nagłówki atrybutów nierezydentnych. Taka sytuacja może chociażby nastąpić, jeśli do jakiegoś pliku jest bardzo dużo twardych dowiązań - dużo różnych nazw. W takim przypadku plikowi przydzielany jest kolejny rekord w MFT, gdzie są trzymane te nadmiarowe atrybuty, a w Attribute_List są trzymane wskaźniki do tychże atrybutów. Ten atrybut pojawia się rzadko, ale jak już jest, to zawsze znajduje się w MFT (z oczywistych przyczyn).

  3. File_Name - zawiera te informacje, które nazwalibyśmy standardowymi, a nie znajdują się w atrybucie Standard_Information. Te dane to chociażby nazwa pliku - NTFS trzyma dwie różne nazwy - długą do 255 znaków Unicode'a (sam nie tworzy nazw z małymi literami, ale je rozróżnia) i krótką DOSową - do 8 znaków. Poza tym tutaj znajduje się informacja o wielkości pliku i wskaźnik do katalogu macierzystego. Tworząc twarde dowiązanie tak naprawdę tworzymy kolejny atrybut File_Name. Plik zostanie ostatecznie usunięty tylko w wypadku kiedy nie ma już żadnej "nazwy". Dodatkowo przechowuje się w tym atrybucie także flagi, informujące o rodzaju pliku (to samo co w Standard_Information). Te flagi aktualizujemy tylko w wypadku zmiany nazwy pliku - aktualna kopia zawsze znajduje się w Standard_Information. Ten atrybut także zawsze jest rezydentny.

  4. Object_ID - GUID (Globally Unique Identifier) - unikalny identyfikator pliku. To jest odpowiednik numeru i-węzła z Ext2. Poza samym numerem pliku (który teoretycznie może się zmienić w trakcie jego życia) mogą znajdować się tutaj także pierwotny numer pliku (ten przydzielony przy tworzeniu), identyfikator woluminu na którym powstał plik oraz identyfikator domeny/serwera powstania pliku - wszyskto po to, żeby można było jednoznacznie zidentyfikować oraz w razie potrzeby odszukać plik. Stosuje się to np. przy tworzeniu dowiązań - pamiętamy wtedy numer pliku, więc nawet w przypadku zmiany nazwy, czy przeniesienia pliku w inne miejsce możemy go znaleźć.

  5. Security_Descriptor - od NTFS 3.0 wszystkie dane (prawa dostępu do pliku, informacje o właścicielu) zostały przeniesione do pliku $Secure w celu poprawienia wydajności. Wcześniej znajdowały się w tym atrybucie.

  6. Volume_Name i Volume_Information - te atrybuty ma tylko plik $Volume - w nim właśnie są przechowywane wszystkie informacje o woluminie - nazwa, flagi stanu woluminu i numery wersji.

  7. Data - zazwyczaj największy atrybut - zawartość pliku. Ciekawe jest to, że plik może mieć kilka atrybutów Data, a co za tym idzie kilka zawartości. Na pierwszy rzut oka może się to wydawać bez sensu, ale pomyślmy chociażby o plikach graficznych, które w dodatkowym atrybucie trzymają miniaturkę. Główna zawartość pliku jest przechowywana w nienazwanym atrybucie Data, a wszystkie inne muszą być jakoś ponazywane. Przy kilku zawartościach pojawia się pytanie o to, co nazywamy wielkością pliku. Projektanci zdecydowali, że rozmiarem pliku będzie wielkość nienazwanego atrybutu. Takie rozwiązanie może spowodować, że mamy na dysku plik, którego główna zawartość (a zatem także oficjalna wielkość) ma rozmiar 1KB, a któraś z nazwanych 1GB. Jeśli wszystkie zawartości pliku są małe (do ok. 1KB), to zawarty jest on w MFT.

  8. Index_Root, Index_Allocation, Bitmap - te atrybuty służą do implementacji katalogów. Dopóki katalog jest mały i cały mieści się w rekordzie MFT, to wszystkie informacje o podkatalogach i zawartych w nim plikach znajdują się w Index_Root, a pozostałe dwa atrybuty nie istnieją. Jeśli jednak katalog jest większy, to istnieją wszystkie trzy i za ich pomocą są zaimplementowane B+-drzewa, na których opiera się struktura katalogów w MFT.

  9. Reparse_Point - jest to wyjątkowy atrybut, służący do implementacji dowiązań symbolicznych oraz montowania innych nośników danych. Pomysł polega na tym, że właściwie dowiązania symboliczne jak i punkty montowania są tym samym - odsyłają program w inne miejsce - więc nie widać powodu dla którego należałoby stosować do tego różne rozwiązania. Tak więc Reparse_Point jest właśnie dowiązaniem symbolicznym i punktem montowania w jednym. Tworząc taki plik wpisujemy do niego adres tego obiektu, do którego ten plik ma się odwoływać. Teraz wszystkie odwołania do tego pliku są "reparsowane" (przeadresowywane) w taki sposób, żeby odwoływać się pod wpisany adres.

  10. EA_Information i EA (Extended Attributes) - FAT trzymał tylko absolutne minimum informacji o pliku - nazwę, prawa dostępu i stemple czasowe. Bardzo szybko okazało się, że to jest za mało - wtedy powstał HPFS (High Performance File System), który rozszerzał FAT-owskie atrybuty właśnie o EA, w którym mogło być trzymane absolutnie cokolwiek, byle miało ograniczoną wielkość (do 64KB). Mogły to być np. informacje o autorze, czy długa nazwa pliku. HPFS był stosowany np. w OS2. Teraz te atrybuty służą zachowaniu kompatybilności z tym systemem.

  11. Logged_Utility_Stream - kolejne 64KB dla programisty, które ten może wykorzystać jak chce. Cechą tego atrybutu jest to, że wszystkie informacje o wszystkich operacjach na nim są zapisywane do dziennika.