(Обратите внимание, что hdparm --fibmap
относится ко всему диску, а не к разделу или любому другому блочному устройству, хранящему ФС. Для этого также требуется 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
, когда это доступно (более новый extent-map ioctl, а не старый медленный block-map ioctl).
# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Как говорит @Kusalananda в комментариях, tar привязан к диску -. Одна из лучших вещей, которую вы можете сделать, это поместить вывод на отдельный диск, чтобы запись не замедляла чтение.
Если вашим следующим шагом будет перемещение файла по сети, я бы посоветовал вам в первую очередь создать tar-файл по сети:
$ tar -cf - xxx/ | ssh otherhost 'cat > xxx.tar'
Таким образом, локальный хост должен только читать файлы, и ему не нужно также учитывать пропускную способность записи, используемую tar. Дисковый вывод из tar поглощается сетевым соединением и дисковой системой на otherhost
.
Or, alternatively, is there any good way to transfer a large number of small files between different folders and between different servers? My filesystem is ext4.
Я регулярно использую Rsync через ssh. Он сохраняет права доступа к файлам, символические ссылки и т. д. при использовании с параметром --archive
:
rsync -av /mnt/data <server>:/mnt
В этом примере локальный каталог /mnt/data
и его содержимое копируются на удаленный сервер внутри /mnt
. Он вызывает ssh для установки соединения. Никакой демон rsync не требуется ни с одной стороны провода.
Эту операцию также можно выполнить между двумя локальными каталогами или с удаленного на локальный.