NTFSologia, cz. II - Historia systemu plików NTFS i wprowadzenie do jego funkcjonalności
Autor: Grzegorz Niemirowski
Opublikowano: 7 kwietnia 2005 | Zaktualizowano: 15 czerwca 2007
Zawartość strony
Wstęp | |
Bootsector | |
MFT | |
Atrybuty plików | |
Kompresja | |
Pliki rozrzedzone | |
Przeczytaj pozostałe części tego artykułu |
Wstęp
W drugiej części cyklu poświęconego systemowi plików NTFS, przyjrzymy się jego strukturze wewnętrznej.
Wolumin NTFS składa się z czterech obszarów:
- bootsectora (sektora startowego), który zawiera podstawowe informacje o woluminie oraz posiada kod uruchamiający Windows NT,
- głównej tablicy plików (Master File Table, MFT), składającej się z plików systemowych przechowujących, m.in. dane o położeniu plików i katalogów, ich atrybuty, plik dziennika, informacje o uszkodzonych sektorach itp,
- danych plików i katalogów,
- kopii zapasowej MFT.
Do początku strony
Bootsector
To pierwszy sektor partycji tworzony podczas formatowania woluminu. Na początku znajduje się trzybajtowa instrukcja skoku, będąca rozkazem w języku maszynowym procesora x86. Jest ona potrzebna, gdyż po niej znajdują się dane i procesor musi przejść do części bootsectora zawierającej kod startowy uruchamiający system operacyjny. Te dane to OEM ID, BPB i rozszerzone BPB (Extended BPB). OEM ID jest ciągiem znaków identyfikujących nazwę i wersję systemu operacyjnego. Systemy Windows NT wpisują tam ciąg „NTFS” (w systemie plików FAT też znajdował się OEM ID), Windows 95 wpisywał w tym miejscu „MSWIN4.0”, natomiast Windows 95 OSR 2 i późniejsze z linii 9x umieszczały „MSWIN4.0”. Po OEMID znajduje się BPB (BIOS parameter block, blok parametrów BIOS-u), zawierajacy m.in. informacje o geometrii dysku, pozwalające kodowi wykonywalnemu zawartemu w bootsectorze na odnalezienie pliku ntldr i uruchomienie Windows. ExtendedBPB pozwala na odnalezienie MFT. Jeśli zdarzy się uszkodzenie klastrów w obrębie MFT, można je przenieść w inne miejsce dysku. Trzeba tylko zmienić zapis w Extended BPB. W przypadku uszkodzenia rozszerzonego BPB, główna tablica plików nie może zostać odnaleziona i Windows uznaje partycję za niesformatowaną.
Tabela 1. Budowa bootsectora | ||
Offset | Rozmiar pola | Zawartość |
0x00 | 3 bajty | Instrukcja skoku |
0x03 | 8 bajtów | OEM ID |
0x0B | 25 bajtów | BPB |
0x24 | 48 bajtów | Rozszerzone BPB |
0x54 | 426 bajtów | Kod startowy |
0x01FE | 2 bajty | Znacznik końca bootsectora |
Tabela 2. Pola w BPB i rozszerzonym BPB | |||
Offset | Rozmiar pola | Przykładowa wartość | Opis |
0x0B | 2 bajty | 00 02 | Ilość bajtów przypadających na sektor podzielona przez 256. |
0x0D | 1 bajt | 08 | Liczba sektorów na klaster. |
0x0E | 2 bajty | 00 | Liczba zarezerwowanych sektorów wyzerowana, ponieważ bootsector jest na początku partycji. Ustawienie niezerowej wartość sprawi, że zamontowanie woluminu stanie się niemożliwe. |
0x10 | 3 bajty | 00 00 00 | Wartość musi być wyzerowana aby wolumin dało się zamontować. |
0x13 | 2 bajty | 00 00 00 | j.w. |
0x15 | 1 bajt | F8 | Deskryptor nośnika określa rodzaj nośnika nieużywanego w Windows 2003.Wartość F8 oznacza twarde dyski. |
0x16 | 2 bajty | 00 00 | Wartość musi być wyzerowana. |
0x18 | 2 bajty | 00 00 | Nie używane |
0x1A | 2 bajty | 00 00 | Nie używane |
0x1C | 4 bajty | 3F 00 00 00 | Nie używane |
0x20 | 4 bajty | 00 00 00 00 | Wartość musi być wyzerowana |
0x24 | 4 bajty | 80 00 80 00 | Nie używane |
0x28 | 8 bajtów | 1C 91 11 01 00 00 00 00 | Całkowita ilość sektorów. |
0x30 | 8 bajtów | 00 00 04 00 00 00 00 00 | Numer logicznego klastra dla pliku $Mft. Pozwala odnaleźć główną tabelę plików. |
0x38 | 8 bajtów | 11 19 11 00 00 00 00 00 | Numer logicznego klastra dla pliku $MftMirr. Określa położenie kopii zapasowej MFT. |
0x40 | 1 bajt | F6 | Ilość klastrów przypadających na rekord w MFT, przy czym liczba dodatnia (od 0x00 do 0x7F) reprezentuje liczbę klastrów na rekord wprost, a liczba ujemna (od 0x80 do 0xFF) oznacza rozmiar rekordu w bajtach wynoszący 2 do potęgi moduł z tej liczby.0xF6 to inaczej -10, oznacza więc, że rekord ma 2|-10| = 210 = 1024 [bajtów]. |
0x41 | 3 bajty | 00 00 00 | Nie używane |
0x44 | 1 bajt | 00 00 00 | Ilość klastrów na bufor indeksujący, obliczana tak jak przy rozmiarze rekordu w MFT. |
0x45 | 3 bajty | 00 00 00 | Nie używane. |
0x48 | 8 bajtów | B4 5C 39 06 D2 56 27 F4 | Numer seryjny woluminu. |
0x50 | 4 bajty | 00 00 00 00 | Nie używane. |
Do początku strony
MFT
Główna tablica plików zawiera wszelkie informacje o sobie i wszystkich innych plikach na dysku, jest bardzo dobrą bazą danych zawierającą co najmniej jeden rekord dla każdego pliku lub katalogu. Kolumnami w tej bazie są atrybuty plików. Rekordy posiadają też nagłówki zawierające sumę kontrolną, wskaźnik do pierwszego atrybutu w rekordzie, wskaźnik do pierwszego wolnego bajtu oraz numer bazowego rekordu MFT dla pliku, którego dotyczy wpis. Jeśli dane opisujące plik nie mieszczą się w jednym rekordzie, to posiada on ich kilka. Sytuacja taka może wystąpić np. przy dużym sfragmentowaniu pliku, wtedy pierwszy jego rekord to rekord bazowy, zawierający informacje o pozostałych. Małe pliki lub katalogi mogą być umieszczane w rekordach w całości, a nie tylko same ich atrybuty. Maksymalny rozmiar pliku/katalogu takiego pliku zależy naturalnie od rozmiaru rekordu. Rekord może mieć różną wielkość zależnie od wielkości klastra oraz wersji NTFS-a, który zwykle oscyluje wokół 1 kilobajta. Główna tablica plików jest w rzeczywistości plikiem o nazwie $Mft, posiadającym częściową kopię zapasową w pliku o nazwie $MftMirr. Dane na temat tego jak duża część MFT znajduje się w kopii zapasowej, są dość rozbieżne.
W Technecie, w opisach Windows 2000 i 2003 widnieje informacja o czterech sektorach, a w przypadku Windows XP – w zależności odwielkości, cztery rekordy lub pierwszy klaster. W opisach NTFS4 spotkać można również wartość 16 lub 3 rekordów. Plik $MftMirr położony jest na końcu woluminu (w Windows NT 3.51 i temu podobnych systemach znajdował się pośrodku przestrzeni woluminu), natomiast $Mft i $MftMirr to tzw. metapliki. Na dysku znajduje się więcej takich plików, a wszystkie z nich mają nazwy zaczynające się od znaku $, nie można ich także normalnie zobaczyć. W starszych Windows NT były widoczne za pomocą polecenia dir /ah wydanego w katalogu głównym. Dla metaplików zarezerwowane jest 16 pierwszych rekordów w MFT (ok. 1 megabajta). Spis metaplików i ich funkcje można znaleźć w tabeli 3.
Ponieważ fragmentacja MFT mogłaby spowodować znaczny spadek wydajności systemu, NTFS rezerwuje domyślnie 12,5% miejsc na dysku na MFT. Ten obszar nazywany jest strefą MFT (MFT zone). Nie powoduje to jednak niewykorzystnia miejsca na dysku, jeśli dostępne miejsce się skończy, pliki są zapisywane w strefie MFT. Jeżeli na woluminie zostanie utworzonych bardzo dużo małych plików, może zajść sytuacja odwrotna – rekordy tych plików nie zmieszczą się w strefie MFT i zostanie ona wtedy powiększona. Systemowe funkcje zwracające ilość wolnego miejsca uwzględniają też wolne miejsce w MFT zone, użytkownik nie jest więc świadom jej rozmiaru i wszystko odbywa się dla niego w sposób właściwy.
Tabela 3. Metapliki przechowywane w MFT | |||
Plik | Nazwa pliku | Numer rekordu | Funkcja pliku |
Główna tablica plików | $Mft | 0 | Zawiera rekordy każdego pliku. |
Kopia zapasowa głównej tablicy plików | $MftMirr | 1 | Pozwala odtworzyć MFT. |
Plik dziennika | $LogFile | 2 | Lista kroków transakcji operacji dyskowych.Zapewnia spójność danych. |
Wolumin | $Volume | 3 | Zawiera informacje o woluminie, m.in. etykietę i wersję. |
Definicje atrybutów | $AttrDef | 4 | Tabela nazw atrybutów, ich numerów i opisów. |
Indeks folderu głównego | Różne źródła podają znak dolara, kropkę albo znak dolara z kropką | 5 | Główny katalog woluminu. |
Mapa bitowa klastrów | $Bitmap | 6 | Informuje o wolnych i zajętych klastrach. |
Sektor startowy | $Boot | 7 | Zawiera podstawowe informacje o woluminie oraz kod startowy. |
Plik uszkodzonych klastrów | $BadClus | 8 | Lista uszkodzonych klastrów. |
Plik zabezpieczeń | $Secure | 9 | Deskryptory zabezpieczeń dla plików. |
Tabela wielkich znaków | $Upcase | 10 | Służy do konwersji małych znaków/liter na odpowiadające im wielkie znaki w standardzie Unicode. |
Plik rozszerzeń NTFS | $Extend | 11 | Wykorzystywany przez rozszerzenia takie jak przydziały, punkty ponownej analizy, identyfikatory obiektów. |
12-15 | Zarezerwowane do przyszłego użycia. |
Do początku strony
Atrybuty plików
Każdy zaalokowany sektor na woluminie NTFS należy do pliku. Wszystkie pliki i katalogi są traktowane jako zestawy atrybutów, do których należą m.in. nazwa, informacje o zabezpieczeniach, a także same dane przechowywane w pliku. Każdy atrybut jest identyfikowany przez kod, a opcjonalnie także przez nazwę. Atrybuty, które są zapisane w rekordzie pliku w MFT, są nazywane atrybutami rezydującymi, a te, które się nie mieszczą, zapisywane są poza MFT, w przestrzeni dyskowej i noszą nazwę nierezydujących. W atrybutach rezydujących zostaje utworzona lista atrybutów (która także jest atrybutem) zawierająca wskazania na położenie atrybutów nierezydujących w celu odnalezienia wszytskich atrybutów pliku. Nazwa pliku oraz znaczniki czasu są zawsze rezydujące. Rekordy katalogów zawierają informacje indeksujące i podobnie jak w przypadku plików, atrybuty katalogów mogą się nie zmieścić w jednym rekordzie.
Duże katalogi są wtedy organizowane w postaci posortowanego drzewa zrównoważonego (balanced tree, B-tree) i posiadają rekordy ze wskaźnikami do zewnętrznych klastrów (buforów indeksowych, index buffers), zawierających wpisy w folderze, które nie mieszczą się w MFT. Przeszukiwanie drzewa zrównoważonego jest dużo szybsze niż listy, szczególnie przy dużej ilości elementów. W przypadku drzewa obszar poszukiwań za każdym razem zmniejsza się kilkukrotnie, zależnie od ilości elementów w węźle. W systemie plików FAT, gdzie stosowana była lista, wpisy w katalogu przeszukiwane były po kolei, dopóki nie został odnaleziony poszukiwany plik/katalog. Co prawda w nowszych systemach korzystających z FAT, takich jak Windows 98, wprowadzono podobne optymalizowanie przeszukiwania, jednak nadal stosowane było liniowe ułożenie wpisów.
Tabela 4. Atrybuty plików i katalogów | |||
Typ atrybutu | Kod | Numer | Opis |
Informacje standardowe | $STANDARD_INFORMATION | #16 0x10 | Zawiera informacje takie jak znaczniki czasu i liczba łączy, w NTFS5.1 także prawa dostępu. |
Lista atrybutów | $ATTRIBUTE_LIST | #32 0x20 | Zawiera lokalizacje rekordów atrybutów, które nie zmieściły się w MFT. |
Nazwa pliku | $FILE_NAME | #48 0x30 | Atrybut powtarzalny dla długich i krótkich nazw plików. Dodatkowe nazwy lub twarde łącza mogą być zapisywane jako dodatkowe atrybuty tego typu. |
Wersja woluminu | $VOLUME_VERSION | #64 0x40 | Wersja woluminu, atrybut usunięty wraz z NTFS 5.0, wcześniej istniał, ale był nieużywany. |
ID obiektu | $OBJECT_ID | #64 0x40 | Identyfikator unikalny w obrębie woluminu, wykorzystywany przez usługę śledzenia łączy, wprowadzony w NTFS 5.0. |
Deskryptor zabezpieczeń | $SECURITY_DESCRIPTOR | #80 0x50 | Identyfikuje właściciela pliku oraz użytkowników, którzy mogą korzystać z pliku, nie znajduje się w NTFS 5.1. |
Nazwa woluminu | $VOLUME_NAME | #96 0x60 | Etykieta woluminu, brak w NTFS 5.1. |
Informacje o woluminie | $VOLUME_INFORMATION | #112 0x70 | Wersja woluminu, w NTFS 5.1 także nazwa. |
Dane | $DATA | #128 0x80 | Dane pliku, jeśli plik posiada strumienie wielokrotne, takich atrybutów ma więcej. |
Indeks główny | $INDEX_ROOT | #144 0x90 | Używany do implementowania katalogów i indeksów. |
Alokacje indeksu | $INDEX_ALLOCATION | #160 0xA0 | Używany w B-drzewie w dużych katalogach i indeksach. |
Mapa bitowa | $BITMAP | #176 0xB0 | Określa użycie struktur B-drzewa. |
Łącze symboliczne | $SYMBOLIC_LINK | #192 0xC0 | Używany do łączy symbolicznych, usunięty w NTFS 5.0, wcześniej istniał, ale nie był używany. |
Punkt ponownej analizy | $REPARSE_POINT | #192 0xC0 | Używany przez punkty ponownej analizy, wprowadzony w NTFS 5.0. |
Informacje o atrybucie rozszerzonym | $EA_INFORMATION | #208 0xD0 | Używany dla zgodności z OS/2. |
Atrybut rozszerzony | $EA | #224 0xE0 | j.w. |
Zestaw właściwości | $PROPERTY_SET | #240 0xF0 | Miał służyć do wspierania Native Structure Storage (NSS). Istniał krótko w NTFS 5.0, został usunięty podczas betatestów. |
Rejestrowany strumień pomocniczy | $LOGGED_UTILITY_STREAM ($LOGGED_TOOL_STREAM) | #256 0x100 | Rejestrowany do dziennika ($LogFile) strumień danych używany przez EFS, pojawił się w NTFS 5.0. |
Do początku strony
Kompresja
Kompresji podlegają bloki składające się z 16 klastrów, które są kompresowane oddzielnie i dzięki temu np. część pliku może zostać skompresowana, a część nie. Podczas kompresji dane z 16 klastrów są zapisywane w mniejszej ilości miejsca. Pozostałe klastry stają się tzw. klastrami wirtualnymi i znajdują się za „prawdziwymi”. Podczas dekompresji wirtualne klastry zostają zapełnione danymi na podstawie danych zapisanych w pozostałych klastrach i w ten sposób odtwarzana jest pierwotna postać pliku. Wszystko odbywa się w sposób automatyczny i przezroczysty dla aplikacji. Kompresję można włączyć lub wyłączyć poprzez ustawienie lub wyłączenie odpowiedniego atrybutu pliku. Włączanie następuje poprzez przesłanie parametru FSCTL_SET_COMPRESSION do funkcji DeviceIoControl, a plik/katalog otrzymuje flagę FILE_ATTRIBUTE_COMPRESSED. Ponieważ dekompresja następuje w pamięci, spadek wydajności nie jest zbyt duży. Kompresja nie może zostać zastosowana na woluminach, które zostały sformatowane z wielkością klastra ponad 4 kB. Z tego też względu wprowadzono wraz z systemem Windows 2000 ograniczenie domyślnej wielkości klastra podczas formatowania właśnie do 4 kB.
Do początku strony
Pliki rozrzedzone
W pliku rozrzedzonym miejsce na dysku alokowane jest tylko dla danych znaczących (niezerowych), zaś ciągi zer nie są zapisywane. Pozwala to na zaoszczędzenie miejsca na dysku. Domyślnie podczas odczytu widoczna jest oryginalna zawartość pliku. Można jednak także wczytać plik bez odtwarzania ciągów zer i/lub zakresów niezaalokowanych danych. Istnieją do tego odpowiednie funkcje WinAPI. NTFS nie wyszukuje automatycznie bloków bajtów o wartości zero, zadaniem aplikacji zapisującej plik jest wskazanie bloków danych, które są zerami i nie mają być zapisane na dysku. Jeśli w jakimś miejscu pliku były dane znaczące, a następnie miejsce to zostało oznaczone jako nieznaczące, dane z tego właśnie miejsca zostaną utracone. Do zarządzania plikami rozrzedzonymi służy polecenie fsutil sparse.
Tabela 5. Domyślne rozmiary klastrów | |
Rozmiar woluminu | Wielkość klastra |
7MB – 512 MB | 512 bajtów |
513 MB – 1024 MB | 1 kB |
1025 MB – 2 GB | 2 kB |
2 GB – 2 TB | 4 kB |
Do początku strony
Przeczytaj pozostałe części tego artykułu
Grzegorz Niemirowski (MVP, MCP) Studiuje na kierunku Electrical and Computer Engineering na Politechnice Warszawskiej. Rozwija program OE PowerTool - dodatek ulepszający Outlook Express. Autor strony www.grzegorz.net, poświęconej Windows, programowaniu, Outlook Express i OE PowerTool. Bierze udział w konstruowaniu satelitów studenckich. |
Do początku strony |