Как вывести «разреженность» файла?

15

Как вывести, сколько номинального размера файла фактически заполнено данными? Как vmtouchпоказывает, сколько файлов в данный момент находится в памяти ...

Я ожидаю, что рабочий процесс будет таким:

$ fallocate -l 1000000 data 
$ measure_sparseness data
100%
$ fallocate -p -o 250000 -l 500000  data
$ measure_sparseness
50%

Временное решение: использование du -bshи du -shи сравнить их.

Vi.
источник
1
связанные: filefragдля любой файловой системы и xfs_bmap -vplдля XFS являются ключевыми инструментами, показывающими, где находятся данные (и где находятся предварительно выделенные неписанные экстенты) при игре с разреженными файлами и пробиванием дырок.
Питер Кордес
filefrag data-> несколько FIBMAP: Invalid argument-> data: 1 extent found...
Vi.
на какой файловой системе? filefrag -eотлично работает на XFS и ext4 по крайней мере. Я не проверял на других. Он использует FIEMAP (карта экстентов) с отступлением к FIBMAP. Если эти ioctlне работают, то это не будет полезно.
Питер Кордес
На тмпфс. У меня filefragнет -eвыбора.
Ви.
Сколько тебе лет e2fsprogs? Я уверен, что это не последняя функция. Там же также -vвариант , который печатает ту же информацию многословной (плюс некоторые дополнительные строки заголовка). Может быть, у вас filefragбудет это. В отличие от xfs_bmapэтого, он явно не указывает дырки отдельными линиями, он просто имеет разрывы в позиции файла. В любом случае, я не удивлен, что tmpfsне поддерживает FIEMAP, потому что нет блочного устройства в качестве резервного хранилища, поэтому нет разумного значения для местоположения экстентов.
Питер Кордес

Ответы:

19

findимеет %Sспецификатор формата, который даже называется "разреженность"

         %S     File's  sparseness.   This  is  calculated as (BLOCKSIZE*st_blocks / st_size).  The exact value you will get for an ordinary file of a certain
                 length is system-dependent.  However, normally sparse files will have values less than 1.0, and files which use indirect  blocks  may  have  a
                 value which is greater than 1.0.   The value used for BLOCKSIZE is system-dependent, but is usually 512 bytes.   If the file size is zero, the
                 value printed is undefined.  On systems which lack support for st_blocks, a file's sparseness is assumed to be 1.0.
$ fallocate -l 1000000 data
$ find data -printf '%S\n'
1.00352
$ fallocate -p -o 250000 -l 500000  data
$ find data -printf '%S\n'
0.507904
Vi.
источник
Интересный. Большинство обычных файлов в системе будут иметь разреженность выше 1,0, у каталогов, программных ссылок и сокетов всегда будет ровно 1,0.
grochmal
Разве некоторые системы не сохраняли (короткие) символические ссылки непосредственно в inode без использования блоков данных вообще? Интересно, какой должна быть редкость? Кроме того, не является ли это определение неправильным, конечно, нормальный (то есть не разреженный) файл должен иметь ноль разреженности? :)
ilkkachu
@grochmal, в ext4 (Linux):, ln -s foo link"разреженность" из link: 0. Сокеты и FIFO имеют нулевую длину, поэтому findпоказывает разреженность 1.
ilkkachu
1

Если у вас findнет этой опции, метод, который работает в UNIX с 70-х годов:

ls -ls file

Который напечатает фактическое количество используемых блоков и самый большой байт, когда-либо написанный. Из этого вы можете легко вычислить, сколько блоков на самом деле не было выделено.

КАРТА
источник
0

В то время как find«s %Sнапечатает вывод кратко, для более детальной информации вы можете посмотреть на sparsetestкотором я писал - с открытым исходным кодом, и на GitHub здесь . Не стесняйтесь изменять его, если вы хотите распечатать (например) каждую лунку.

Блог статья показывает проблемы с редкими ассигнованиями здесь , используя sparsetestдля отладки этой проблемы.

abligh
источник
Может ли он напечатать «карту» экстентов в файле, например, vmtouch -vраспечатать карту кэшированных областей в файле?
Ви.
@Vi. Я написал это довольно давно и забыл некоторые детали - на самом деле он создает разреженный файл, записывает в него данные, а затем печатает статистику. Вы просто хотите бит создания статистики. Для печати отверстий вам нужно lseekс SEEK_HOLEи SEEK_DATA. Легко сделать.
abligh