Есть ли команда, которая выведет начальный и конечный блоки любого файла?
Есть ли команда, которая выведет начальный и конечный блоки любого файла?
Ответы:
Я не уверен на 100%, что это то, что вы ищете, но я верю, что вы можете сделать это с помощью команды hdparm
, особенно с ее --fibmap
переключателем.
выдержка
--fibmap
When used, this must be the only option given. It requires a
file path as a parameter, and will print out a list of the block
extents (sector ranges) occupied by that file on disk. Sector
numbers are given as absolute LBA numbers, referenced from sector
0 of the physical device rather than from the partition or
filesystem. This information can then be used for a variety of
purposes, such as examining the degree of fragmenation of larger
files, or determining appropriate sectors to deliberately corrupt
during fault-injection testing procedures.
This option uses the new FIEMAP (file extent map) ioctl() when
available, and falls back to the older FIBMAP (file block
map) ioctl() otherwise. Note that FIBMAP suffers from a 32-bit
block-number interface, and thus not work beyond 8TB or 16TB.
FIBMAP is also very slow, and does not deal well with
preallocated uncommitted extents in ext4/xfs filesystems, unless a
sync() is done before using this option.
Скажем, у нас есть образец файла.
$ echo "this is a test file" > afile
Теперь, когда мы бежим hdparm
.
$ 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
Другой хороший метод для определения начала и конца файла - это filefrag
. Вам нужно будет использовать соответствующие переключатели, чтобы получить желаемый результат. Одним из преимуществ этого инструмента hdparm
является то, что его может запустить любой пользователь, поэтому нет sudo
необходимости. Вам нужно будет использовать -b512
переключатель, чтобы выходные данные отображались в 512-байтовых блоках. Также нам нужно сказать, filefrag
чтобы быть многословным.
$ filefrag -b512 -v afile
Filesystem type is: ef53
File size of afile is 20 (8 block of 512 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 7: 282439184.. 282439191: 8: eof
afile: 1 extent found
Третий метод получения файловых LBA - это использование debugfs
. Этот метод потребует немного математики, но я подумал, что важно показать, как можно преобразовать значение экстентов, сообщаемое debugfs
LBA, в те, которые могут быть любопытными.
Итак, начнем с inode файла.
$ ls -i afile
6560281 afile
ПРИМЕЧАНИЕ: мы также могли бы использовать имя файла внутри, debugfs
но для этой демонстрации я собираюсь использовать вместо этого inode.
Теперь давайте рассмотрим stat
информацию debugfs
о нашем иноде.
$ 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: 0x52bff8a1:a9f08020 -- Sun Dec 29 05:25:37 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
Важная информация находится в разделе экстентов. Это фактически блоки файловой системы, которые используются этим индексом. Нам просто нужно конвертировать их в LBA. Мы можем сделать это с помощью следующего уравнения.
ПРИМЕЧАНИЕ. Предполагая, что наша файловая система использует блоки размером 4 КБ, а базовое оборудование использует 512-байтовые блоки, нам нужно умножить значения на 8.
beginning LBA = (BEGIN EXTENT) * 8
ending LBA = (((ENDING EXTENT) + 1) * 8) - 1
Таким образом, в нашем примере наш начальный и конечный экстенты одинаковы, поскольку наш файл соответствует одному экстенту.
beginning LBA = 35304898 * 8 = 282439184
ending LBA = ((35304898 + 1) * 8) - 1 = 282439191
Таким образом, наши LBA 282439184..282439191.
filefrag
.
debugfs
.
filefrag
с доступными размерами блоков 1024 и 2048 .. debugfs
с большими размерами файлов : 0 - 12187 .. я не тороплюсь и пойму ... это большая помощь, спасибо ...
(Обратите внимание, что это hdparm --fibmap
относится ко всему диску, а не к разделу или какому-либо другому blockdev, содержащему FS. Это также требует root.)
filefrag -e
работает хорошо и использует универсальный и эффективный FIEMAP
ioctl , поэтому он должен работать практически на любой файловой системе (включая часто странный BTRFS, даже для файлов, сжатых BTRFS). Он вернется к FIBMAP для файловых систем / ядер без поддержки FIEMAP.
$ filefrag xpsp3.vdi # some old sparse disk image I had lying around
xpsp3.vdi: 110 extents found
$ filefrag -e xpsp3.vdi
Filesystem type is: 58465342
File size of xpsp3.vdi is 5368730112 (1310726 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 5: 1322629241..1322629246: 6:
1: 13.. 13: 1322620799..1322620799: 1: 1322629247:
2: 15.. 47: 1323459271..1323459303: 33: 1322620800:
...
160: 899498.. 915839: 1325792977..1325809318: 16342: 1325725438:
161: 1307294.. 1307391: 1323938199..1323938296: 98: 1325809319: last
xpsp3.vdi: 110 extents found
Если вы используете xfs, то xfs_bmap
имеет более хороший вывод: он показывает вам, где есть дыры, а filefrag
просто имеет следующий экстент, начиная с более позднего сектора. Он использует блоки 512B, а не размер блока файловой системы. (обычно 4k в Linux). Он показывает, в какой группе размещения находится каждый экстент и как он выровнен по границам полосы RAID.
$ xfs_bmap -vvpl xpsp3.vdi # the extra -v prints a key to the flags
xpsp3.vdi:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS
0: [0..47]: 10581033928..10581033975 13 (83912..83959) 48 01111
1: [48..103]: hole 56
2: [104..111]: 10580966392..10580966399 13 (16376..16383) 8 01010
3: [112..119]: hole 8
...
322: [10458352..10459135]: 10591505592..10591506375 13 (10555576..10556359) 784 01111
323: [10459136..10485807]: hole 26672
FLAG Values: # this part is only here with -vv
010000 Unwritten preallocated extent
001000 Doesn't begin on stripe unit
000100 Doesn't end on stripe unit
000010 Doesn't begin on stripe width
000001 Doesn't end on stripe width
-l
избыточно, когда -v
используется, но по какой-то причине я всегда печатаю -vpl
. -pl
более компактный вывод.
filefrag
и другое xfs_bmap
покажет вам заранее выделенные экстенты.$ fallocate --length $((1024*1024*8)) prealloced_file
$ filefrag -e prealloced_file
Filesystem type is: 58465342
File size of prealloced_file is 8388608 (2048 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 2047: 1325371648..1325373695: 2048: last,unwritten,eof
prealloced_file: 1 extent found
$ xfs_bmap -vvpl prealloced_file
prealloced_file:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS
0: [0..16383]: 10602973184..10602989567 13 (22023168..22039551) 16384 10010
FLAG Values:
010000 Unwritten preallocated extent
001000 Doesn't begin on stripe unit
000100 Doesn't end on stripe unit
000010 Doesn't begin on stripe width
000001 Doesn't end on stripe width
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=10000
40960 bytes (41 kB) copied, 0.000335111 s, 122 MB/s
$ xfs_bmap -vpl prealloced_file
prealloced_file:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS
0: [0..16383]: 10602973184..10602989567 13 (22023168..22039551) 16384 10010
1: [16384..79999]: hole 63616
2: [80000..80895]: 10603013120..10603014015 13 (22063104..22063999) 896 00111
# oops, wrote past EOF and extended the file, instead of in the middle of the preallocated extent
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=100
40960 bytes (41 kB) copied, 0.000212986 s, 192 MB/s
$ xfs_bmap -vpl prealloced_file
prealloced_file:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS
0: [0..16383]: 10602973184..10602989567 13 (22023168..22039551) 16384 10010
1: [16384..79999]: hole 63616
2: [80000..80895]: 10603013120..10603014015 13 (22063104..22063999) 896 00111
# If you check *right away*, XFS's delayed allocation hasn't happened yet.
# FIEMAP on xfs only reflects allocations, which lag behind completed writes. fsync first if you need it, IIRC.
$ xfs_bmap -vpl prealloced_file
prealloced_file:
EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL FLAGS
0: [0..799]: 10602973184..10602973983 13 (22023168..22023967) 800 10111
1: [800..879]: 10602973984..10602974063 13 (22023968..22024047) 80 01111
2: [880..16383]: 10602974064..10602989567 13 (22024048..22039551) 15504 11010
3: [16384..79999]: hole 63616
4: [80000..80895]: 10603013120..10603014015 13 (22063104..22063999) 896 00111
$ filefrag -e prealloced_file
Filesystem type is: 58465342
File size of prealloced_file is 41000960 (10010 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 99: 1325371648..1325371747: 100: unwritten
1: 100.. 109: 1325371748..1325371757: 10:
2: 110.. 2047: 1325371758..1325373695: 1938: unwritten
3: 10000.. 10111: 1325376640..1325376751: 112: 1325373696: last,eof
prealloced_file: 2 extents found
hdparm --fibmap
полезно, только если вы хотите, чтобы номер сектора относился ко всему жесткому диску , а не к разделу, в котором находится файловая система. Он не работает поверх программного RAID (или, вероятно, чего-то еще между файловой системой и жестким диском). Также требуется рут. Несмотря на название опции, она фактически использует, FIEMAP
когда доступно (более новый ioctl карты экстентов, а не старый медленный ioctl карты блоков).
# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Итак, для данного файла вы хотите знать, какие номера блоков диска содержат начало и конец этого файла.
debugfs (8) выглядит многообещающе для ext2 / 3/4 FS
stat (1), ls -i, lsof (8) предоставляют номер инода, но не больше о дисковых блоках.
head / tail --bytes = 1024 полезно для содержимого файлов, но не для блоков на диске.
dd (1) будет тем, что вы хотите проверить содержимое блока - будьте внимательны к разнице между параметрами seek = и skip = и избегайте = / dev / ..., если вы действительно не хотите, чтобы выходной файл был устройством ,
hdparm --fibmap
перечислит блоки, которые занимает файл. Обратите внимание, что они не могут быть смежными, поэтому «начало и конец» не имеет смысла.
--fibmap
. Также вам нужно указать имя файла с ним. Пример: hdparm --fibmap afile
.
hdparm
был на уровне всего диска, никогда раньше не использовал его для файлов.