Длинные файлы


Сложнее обстоит дело с файлами длиной более 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 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


В результате, если нам повезло, то файл полностью восстановлен.


Содержание раздела