Następna strona Poprzednia strona Spis treści

10. Odzyskiwanie bloków danych

Ta czêśæ jest albo bardzo łatwa, albo trudna, w zależności od tego, czy plik który chcesz odzyskaæ zajmował wiêcej niż 12 bloków.

10.1 Małe pliki

Jeżeli plik ma mniej niż 12 bloków, numery wszystkich bloków, które on zajmuje zapisane są w jednym iwêźle. Możesz odczytaæ je po wykonaniu polecenie stat dla tego iwêzła. Ponadto, w debugfs jest polecenie, które automatycznie odzyskuje taki plik. Weźmy ten sam przykład co poprzednio:

debugfs:  stat <148003>
Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 6065
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 12
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
594810 594811 594814 594815 594816 594817
TOTAL: 6

Plik ten zajmuje sześæ bloków. Ponieważ jest to mniej niż 12, możemy użyæ debugfs, aby zapisaæ plik w nowym miejscu, na przykład /mnt/recovered.000:

debugfs:  dump <148003> /mnt/recovered.000

Oczywiście można to zrobiæ również, posługując siê fsgrab. Pokażê jak wygląda takie przykładowe wywołanie:

# fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recovered.000
# fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recovered.000

Zarówno przy korzystaniu z debugfs jak i fsgrab, na koñcu pliku /mnt/recovered.000 pozostaną śmieci. Nie ma to wiêkszego znaczenia. Łatwo można siê ich pozbyæ. Najprostszą metodą jest odczytanie pola Size w iwêźle i wpisanie tej wartości za opcją bs komendy dd:

# dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065

Może siê okazaæ, że jeden lub wiêcej z bloków zostało straconych, bowiem zostały już nadpisane. Jeżeli tak bêdzie, po prostu nie miałeś szczêścia: bloki te odeszły już na zawsze. (Wybraź sobie, że odmontowałeś je wcześniej!)

10.2 Wiêksze pliki

Problem pojawia siê, gdy plik zajmuje wiêcej niż 12 bloków danych. Przypadek ten wymaga pewnej wiedzy o tym jak zbudowany jest system plików UNIX-a. Dane pliku przechowywane są w jednostkach zwanych `blokami'. Bloki te są numerowane sekwencyjnie. Każdy plik ma również `iwêzeł', w którym przechowywane są informacje typu: właściciel, prawa dostêpu i typ. Podobnie jak bloki, iwêzły są numerowane sekwencyjnie, chociaż mają one różne numeracje. Pozycja w katalogu odpowiadająca plikowi składa siê z jego nazwy i numeru iwêzła.

Jednak na postawie tych informacji jądro nie jest jeszcze w stanie odnaleźæ na partycji danych odpowiadających jednej z pozycji w katalogu. Żeby to umożliwiæ, iwêzeł przechowuje położenia bloków danych zajmowanych przez plik. Zorganizowane jest to w nastêpujący sposób:

Przeczytaj to jeszcze raz: wiem, że to jest skomplikowane, ale bardzo ważne.

Niestety wszystkie implementacje jądra, aż do wersji 2.0.36 podczas kasowania pliku zerują bloki pośrednie (podwójnie pośrednie, itd.). Jeśli Twój plik jest wiêkszy niż 12 bloków, nie masz gawarancji, że bêdzie możliwe odnalezienie numerów wszystkich jego bloków, nie mówiąc już nic o ich zawartości.

Jedyną metodą jaką udało mi siê znaleźæ, jest oparcie siê na założeniu, że plik nie był pofragmentowany. Jeżeli był, masz poważny problem. Zakładając, że plik nie był pofragmentowany, istnieje kilka sekcji bloków danych, w zależności od tego ile bloków danych zajmuje plik:

0 do 12

Numery bloków przechowywane są w iwêźle, jak to było opisane wcześniej.

13 to 268

Po blokach bezpośrednich, odlicz jeden na blok pośredni, dalej znajduje siê 256 bloków danych.

269 do 65804

Tak jak poprzednio jest: 12 bezpośrednich bloków, (nieprzydatny) blok pośredni i 256 bloków. Po tym wszystkim nastêpuje (nieprzydatny) podwójnie pośredni blok oraz 256 powtórzeñ jednego (nieprzydatnego) bloku pośredniego i 256 bloków danych.

65805 lub wiêcej

Położenie piewszych 65804 bloków jak wyżej. Potem potrójnie pośredni blok i 256 powtórzeñ `sekwecji podwójnie pośredniej'. Każda podwójnie pośrednia sekwencja zawiera (nieprzydatny) podwójnie pośredni blok, po którym nastêpuje 256 powtórzeñ jednego (nieprzydatnego) bloku pośredniego i 256 bloków danych.

Oczywiście, nawet jeśli numery bloków, które przyjêliśmy, są poprawne, nie ma żadnych gwarancji, że dane są w nich są nienaruszone. Dodatkowo, im dłuższy był plik, tym mniejsze szanse, że system operacyjny zapisał go bez żadnej fragmentacji (za wyjątkiem wyjątkowych sytuacji).

Założyłem, że rozmiar Twoich bloków wynosi 1024 bajty, tyle ile wartośæ standardowa. Jeśli Twój blok jest wiêkszy, niektóre z liczb podanych wyżej zmienią siê. Sprecyzujmy: dopóki numer każdego bloku ma długośæ 4 bajtów, rozmiarbloku/4 jest liczbą numerów bloków, które mogą byæ przechowane w każdym bloku pośrednim. Każde wystąpienie liczby 256 we wcześniejszym opisie, zastąp na rozmiarbloku/4. Zmianie ulegną również ograniczenia na ilośæ wymaganych bloków.

Popatrz na przykładowe odzyskiwanie dużego pliku.

debugfs:  stat <1387>
Inode: 148004   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 1851347
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 3616
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8583
TOTAL: 14

Wydaje siê, że mamy pewne szanse, że plik nie jest pofragmentowany. Pewne jest tylko, że pierwsze 12 bloków, których numery są zawarte w iwêźle, jest `po kolei'. Możemy wiêc odtworzyæ te bloki:

# fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recovered.001

Nastêpny blok, wymieniony w iwêźle, 8326, jest blokiem pośrednim, który ignorujemy. Mamy jednak nadziejê, że nastepne 256 bloków jest naszymi blokami danych (numery 8327 do 8582).

# fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recovered.001

Ostatnim blokiem wymienionym w iwêźle jest 8583. Nadal zakładamy, że istnieje ciągłośæ w blokach. Jest to jednak uzasadnione bowiem: ostatnim blokiem danych był blok o numerze 8582 (8327 + 255). Blok 8583 jest podwójnie pośredni i może byæ zignorowany. Teraz może nastąpiæ do 256 powtórzeñ bloku pośredniego (który można pominąæ) i 256 bloków danych. Trochê arytmetyki i już można pisaæ kolejne polecenie. Zauważ, że pominêliśmy podwójnie pośredni blok 8583 oraz pośredni blok 8584 i rozpoczêliśmy czytaæ dane od bloku numer 8585.

# fsgrab -c 256 -s 8585 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 8842 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9099 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9356 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9613 /dev/hda5 >> /mnt/recovered.001
# fsgrab -c 256 -s 9870 /dev/hda5 >> /mnt/recovered.001

Dodajmy to wszystko, zapisaliśmy do tej pory 12 + (7 * 256) bloków, co daje 1804. Wyniki polecenia `stat' dla iwêzła dały nam `blockcount' (liczba bloków) równe 3616. Niestety są to bloki o rozmiarze 512 bajtów (zaszłośæ z UNIX-a), na prawdê potrzebujemy wiêc 3616/2 = 1808 bloków o rozmiarze 1024 bajty. Oznacza to, że musimy jeszcze odnaleźæ cztery bloki. Ostatni przeczytany blok danych miał numer 10125. Tak jak to robiliśmy do tej pory, pomijamy blok pośredni (numer 10126) i możemy już zapisaæ ostatnie cztery bloki.

# fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recovered.001

Przy pewnym szczêściu udało nam siê odzyskaæ cały plik.


Następna strona Poprzednia strona Spis treści