При ответе на этот вопрос U & L под названием: Какую команду я использую, чтобы увидеть начальный и конечный блок файла в файловой системе? Я попытался выяснить, возможно ли определить LBA файла, используя его индекс.
Мой ответ определил, что я мог бы использовать hdparm
как один метод для нахождения LBA:
$ sudo hdparm --fibmap afile
afile:
filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 282439184 282439191 8
Но мне было любопытно, был ли какой-нибудь метод, использующий индекс файла, чтобы также получить LBA; без использования hdparm
.
Я думаю , что может быть альтернативные методы , скрывающиеся в инструментах filefrag
, stat
, debugfs
и , tune2fs
но дразнить его ускользает меня.
Кто-нибудь может придумать альтернативы?
Вот некоторые из моих исследований, которые могут быть полезны тем, кто достаточно смел, чтобы попытаться ответить на этот вопрос.
filefrag
Я подозреваю, что вы могли бы использовать инструмент, filefrag
чтобы сделать это, в частности, используя результаты его -e
переключения, возможно, выполнив несколько вычислений, чтобы добраться туда, с которыми я не очень знаком.
образец вывода
$ filefrag -e afile
Filesystem type is: ef53
File size of afile is 20 (1 block of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 35304898.. 35304898: 1: eof
afile: 1 extent found
иноды
Еще один потенциальный метод, который, как я подозреваю, может иметь потенциал, - это использовать информацию об индексах файла, либо напрямую, либо с помощью сложной математики, которая плохо документирована во внутренних сетях.
пример
Сначала мы узнаем инод файла. Мы можем сделать это, используя stat
команду или ls -i
.
стат
$ stat afile
File: ‘afile’
Size: 20 Blocks: 8 IO Block: 4096 regular file
Device: fd02h/64770d Inode: 6560281 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ saml) Gid: ( 1000/ saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-12-27 18:40:12.788333778 -0500
Modify: 2013-12-27 18:40:23.103333073 -0500
Change: 2013-12-27 18:44:03.697317989 -0500
Birth: -
ls -i
$ ls -i
6560281 afile
С информацией инода в руке, теперь мы можем открыть файловую систему этот файл находится по использованию инструмента debugfs
.
ПРИМЕЧАНИЕ. Для определения файловой системы, в которой находится файл, вы можете использовать команду df <filename>
.
Теперь, если мы запустим debugfs
и запустим команду, stat <inode #>
мы можем получить список экстентов, которые содержат данные этого файла.
$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281 Type: regular Mode: 0664 Flags: 0x80000
Generation: 1999478298 Version: 0x00000000:00000001
User: 1000 Group: 1000 Size: 20
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
atime: 0x52be0fdc:bbf41348 -- Fri Dec 27 18:40:12 2013
mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body:
selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898
Теперь у нас есть информация о экстентах выше, и вот тут я теряюсь и не знаю, как действовать дальше.
Ссылки
источник
filefrag -b512 -v ..
скажете "physical_offset: 211787168 .. 211795719", это будет равно LBA? Похоже, что это джайв с тем же файлом сhdparm --fibmap
, 211787168..211795719. Если я уроню-b512 -v
и использую def. 1024, и попытка мульт. на 8, 26473396⋅8..26474464⋅8, я получаю 211787168..211795712, что близко, но немного не так. Я думаю, что 2-е значение должно быть (26474465⋅8) -1 = 211795719, хотя не знаю почему.Оказывается, что преобразование из экстентов в LBA на самом деле довольно просто, если вы понимаете, откуда приходят цифры. Ответ @StephaneChazelas имел решающее значение для достижения этого понимания.
Исходный вывод debugfs
Используя следующий пример, который был упомянут в вопросе.
С информацией о экстентах мы можем сделать следующие вычисления. Но нам нужен еще один кусок информации. Размер блока базовой файловой системы. Вы можете использовать эту команду, чтобы получить ее.
Размер блока
Преобразование из экстентов в LBA
Таким образом, ключевое преобразование, которое нужно распознать, заключается в том, что LBA находятся в 512-байтовых единицах, а вышеприведенная
debugfs
команда, которая сообщила о количестве экстентов, сообщает об этом в 4096-байтовых блоках.Итак, 4096/512 = 8. Поэтому нам нужно умножить экстенты на 8, чтобы преобразовать их в значения LBA.
Таким образом, следующая математика даст нам начало LBA:
Так каков наш финал LBA? Чтобы получить это, мы должны признать, что наш инод помещается внутри одного блока, поэтому его конечный экстент совпадает с его начальным экстентом. Для расчета конечного LBA мы можем использовать это уравнение.
Итак, выполняя этот расчет:
Подтверждение результатов
Глядя на оригинальный
hdparm
вывод:Мы видим, что все совпадает.
Другой пример
Просто чтобы убедиться, что мы здесь, вот большой файл в качестве второго примера.
Вот экстенты inode.
Теперь мы делаем преобразования из экстентов в LBA.
И мы подтверждаем.
И мы снова подходим.
источник