
Какие функции используются для работы с разреженными файлами в Linux? (допустим, на языке C, замечания по другим системам приветствуются), например:
- сделать отверстие внутри файла, удалив часть его внутренней части
- исследовать структуру, например, генерировать последовательность пар, обозначающих начало и конец отдельных непрерывных блоков данных
- разделить файл на два в некоторой точке, переназначив диапазон блоков (т.е. без перемещения фактических данных)
- исследовать иноды и другие соответствующие аспекты? (возможно, можно назначить некоторые блоки нескольким файлам способом копирования при записи?)
Контекст:
Первоначальный вопрос, который пришел мне в голову и с которого я пришел, был после man rsync
варианта --sparse
:
Почему rsync
опция --sparse
конфликтует с --inplace
?
Это ограничение вызовов файловой системы API?
С точки зрения структуры данных, если исходный разреженный файл рассматривается как последовательность ненепрерывных блоков данных, то я бы ожидал от "r"syncing освобождения в месте назначения тех диапазонов, которых нет в источнике, выделения недостающих, а остальные обновления соответствующим образом (даже при использовании стандартного алгоритма хэширования rsync, обрабатывающего все оставшиеся последовательности как одну или запускающего каждую по отдельности).
Ссылка:
man rsync
-S, --sparse Try to handle sparse files efficiently so they take up less space on the destination. Conflicts with --inplace because it's
невозможно перезаписать данные разреженным образом.
решение1
Разреженные файлы разработаны так, чтобы быть прозрачными для пользовательского пространства: дыры создаются путем поиска прошлых неиспользуемых областей и считываются как блоки нулей. Их нельзя обнаружить с помощью стандартных API пользовательского пространства, по крайней мере пока — какуказалкСтефан Шазелас, по крайней мере Solaris и Linux поддерживают SEEK_DATA
иSEEK_HOLE
lseek(2)
флаги, которые позволяют программам пользовательского пространства находить дыры, и эти флаги могут бытьдобавлено в POSIXв какой-то момент.
Это объясняет несовместимость между rsync
' --sparse
и --inplace
параметрами: при записи в существующий файлпортативнов существующих данных не могут быть созданы дыры. --sparse
работает путем перезаписи всего файла, пропуская (длинные) последовательности нулей, что приводит к разреженным файлам в ОС и файловых системах, которые их поддерживают.
В Linux вы можете получить сведения о разреженности файлов с помощьюfiemap
ioctl, и e2fsprogs
'filefrag(8)
; видетьПодробная разреженная информация о файлах в Linux. На стороне письма вы можете использоватьfallocate(2)
(и удобныйfallocate(1)
утилита) для проделывания дыр в существующем файле, делая его разреженным, если дыры покрывают целые блоки. Поддержка зависит от файловой системы — в настоящее время эти операции поддерживают только XFS, btrfs, ext4 и tmpfs. Последние ядра (начиная с 4.1) иоченьпоследние версии util-linux
поддерживают вставку дыр в файлы, сдвигая содержимое после дыры ( fallocate -i
, введено в util-linux
версии 2.30, которая должна быть выпущена в ближайшее время).
Ваши последние два вопроса — это хирургическое вмешательство в файловую систему, и я не уверен, что существует какой-либо универсальный системный вызов или ioctl, доступный для выполнения таких операций. reflink
-совместимые файловые системы позволяют файлам обмениваться своим содержимым; этого можно добиться с помощьюи ioctlFICLONE
FICLONERANGE
.