Эта часть может быть очень легкой и довольно сложной, в зависимости от того, занимал ли удаленный файл больше 12 блоков или нет.
Короткие файлы
Если файл занимал не больше 12 блоков, то все их номера хранятся непосредственно в inode. Вы можете просмотреть их командой
stat. Более того,
debugfs имеет команду, позволяющую восстановить файл автоматически. Например:
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
|
Файл занимает 6 блоков. Так как 6 меньше 12, даем команду
debugfs записать файл в новое место, например
/mnt/recovered.000:
debugfs: dump <148003> /mnt/recovered.000
|
Также можно это сделать с помощью
fsgrab. Пример:
# fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recovered.000
# fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recovered.000
|
В обоих случаях (как
debugfs, так и
fsgrab) в конце
/mnt/recovered.000 будет мусор. Впрочем, это не так уж важно. Самый простой способ убрать его - использовать значение поля
Size из inode с ключом
bs команды
dd:
# dd count=1 if=/mnt/recovered.000 of=/mnt/resized.000 bs=6065
|
Конечно
существует вероятность, что один или несколько блоков вашего файла были
перезаписаны. Если это так, то вам не повезло - данные этого блока
навсегда потеряны.
Длинные файлы
Сложнее
обстоит дело с файлами длиной более 12 блоков. Необходимо пояснить, как
устроена файловая система UNIX. Данные файла хранятся в так называемых
"блоках". Эти блоки пронумерованы. Для каждого файла также имеется
"inode" (от английского information node), где хранится информация о
владельце, правах, типе файла и т. п. Также как и блоки, inode
пронумерованы (хотя нумерация ведется независимо от блоков). Каталоги
файловой системы содержат имя файла и номер inode.
Кроме того, для
того, чтобы ядро знало, где искать данные, соответствующие элементу
каталога (файлу), в inode следующим образом размещается информация о
блоках с данными файла:
- Номера первых 12 блоков хранятся непосредственно в inode; их еще иногда называют блоками с прямой адресацией (direct blocks).
- В inode хранится номер блока, в котором хранятся номера еще 256 блоков данных. Иногда его называют блок косвенной адресации (indirect block).
- В inode хранится номер блока, в котором хранятся 256 номеров блоков косвенной адресации. Иногда этот блок называют блоком двойной косвенной адресации (doubly indirect block).
- В inode хранится номер блока, в котором хранятся 256 номеров блоков двойной косвенной адресации. Его называют блоком тройной косвенной адресации (triply indirect block).
Прочтите еще раз: я знаю, что это непросто, но также и очень важно.
Версии
ядра до 2.0.36 включительно при удалении файла обнуляют блоки косвенной
адресации (а также блоки двойной косвенной адресации и т. д.). Так что
если ваш файл был длинной более 12 блоков, нет никакой гарантии, что вы
сможете выявить даже номера блоков с данными, не говоря уже о самих
данных.
Единственный способ, который я нашел - это предположить,
что файл не был фрагментирован; если был, то у вас проблемы. Если же
предполагать, что файл не был фрагментирован, то, в зависимости от
количества блоков с данными файла, возможно следующее расположение
блоков, описывающих местоположение файла:
- 0 - 12
- Номера блоков хранятся в inode, как описано выше.
- 13 - 268
- После блоков с прямой адресацией идет блок косвенной адресации и далее 256 блоков с данными.
- 269 - 65804
- Как
и в прошлом случае, в начале 12 блоков с прямой адресацией, блок
косвенной адресации и 256 блоков данных. Далее блок двойной косвенной
адресации, за ним 256 групп блоков, состоящих из одного блока косвенной
адресации и 256 блоков данных.
- 65805 и более
- Расположение
первых 65804 блоков указано выше. Далее один блок тройной косвенной
адресации и 256 повторений групп "двойной косвенной адресации". Каждая
такая группа состоит из блока двойной косвенной адресации, за которым
идет 256 групп из одного блока косвенной адресации и 256 блоков данных.
Даже если номера блоков данных правильны, нет никакой гарантии, что данные
в них не перезаписывались. К тому же, чем больше файл, тем меньше шансов,
что он был записан без фрагментации (кроме некоторых особых случаев).
Заметьте, что я предполагал, что размер вашего блока 1024 байта, так как
это стандартное значение. Если ваши блоки больше, некоторые числа,
указанные выше, изменятся. В частности: так как номер блока занимает 4
байта, то количество номеров блоков, которые могут быть размещены в блоке
косвенной адресации равно размер_блока/4. Так что везде, где выше
встречается число 256, меняйте его на размер_блока/4. Количество требуемых
для размещения файла блоков также нужно изменить.
Пример восстановления длинного файла:
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
|
В данном случае
шансы того, что файл не фрагментирован, довольно велики: первые 12
блоков, перечисленные в inode, (блоки с данными) идут подряд. Начнем с
того, что восстановим их:
# fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recovered.001
|
Следующий
блок указанный в inode (8326) - блок косвенной адресации, который мы
можем игнорировать, так как предполагаем, что за ним идут блоки данных
(с 8327 по 8582).
# fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recovered.001
|
Последний блок, указанный в inode имеет номер 8583. Заметьте, если
предположить, что файл не фрагментирован, то пока все нормально: последний
блок данных, записанный нами имеет номер 8582, то есть 8327 + 255. Блок
8583 - блок двойной косвенной адресации, его можно игнорировать. За ним
идут до 256 групп состоящих из блока косвенной адресации (который мы также
игнорируем), и 256 блоков данных. Быстренько выполнив несложные
арифметические подсчеты, выполняем следующие команды (заметьте, что мы
пропускаем блок двойной косвенной адресации 8583 и следующий за ним (как мы
надеемся) блок косвенной адресации 8584 и начинаем с блока 8525):
# 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
|
Итого мы записали 12 + (7 * 256) блоков, то есть 1804. В соответствие с
результатом команды "stat" число блоков в файле было равно 3616; считается,
что это блоки длиной 512 байт (пережиток с UNIX), поэтому, в
действительности, нам надо 3616/2 = 1808 блоков длиной 1024 байт. То есть,
нам нужно записать еще четыре блока. Последний записанный блок имел номер
10125. Также, как и раньше, пропускаем блок косвенной адресации (номер 10126)
и записываем последние четыре блока:
# fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recovered.001
|
В результате, если нам повезло, то файл полностью восстановлен.
Источник : citforum.ru