IOCTL-FIDEDUPERANGE(2)

ИМЯ
ioctl_ficlonerange - сделать некоторые данные одного файла общими с другим файлом

ОБЗОР
#include <sys/ioctl.h>
#include <linux/fs.h>

int ioctl(int src_fd, FIDEDUPERANGE, struct file_dedupe_range *arg);

ОПИСАНИЕ
Если файловая система поддерживает общее файловое физическое хранилище между несколькими файлами, то эту операцию ioctl(2) можно использовать для того, чтобы часть данных файла src_fd появилась в файле dest_fd в виде общего пространства на носителе, если данные файлов одинаковы («дедупликация», deduplication). Оба файла должны располагаться в одной файловой системе. Это сокращает затраты на место, позволяя хранить в файловой системе только одну копию данных.Если выполняется запись в эту общую область, то файловая система должна гарантировать, что изменения будут видны только в файле, в который производится запись. Такое поведение часто называют как «копирование при записи» (copy on write).

Данный ioctl выполняет операцию «сравнения и создания общей области при совпадении» с не более src_length байт из файлового дескриптора src_fd по смещению src_offset. Данная информация передаётся в структуре следующего вида:

    struct file_dedupe_range {
        __u64 src_offset;
        __u64 src_length;
        __u16 dest_count;
        __u16 reserved1;
        __u32 reserved2;
        struct file_dedupe_range_info info[0];
    };

Дедупликация атомарна для одновременной записи, поэтому для получения корректной дедуплицированной копии не нужно получать блокировки.

Поля reserved1 и reserved2 должны быть равны нулю.

Назначения для операции дедупликации передаются в массиве в конце структуры. Количество назначений задаётся в dest_count, а информация о назначении задаётся в следующем виде:

    struct file_dedupe_range_info {
        __s64 dest_fd;
        __u64 dest_offset;
        __u64 bytes_deduped;
        __s32 status;
        __u32 reserved;
    };

Целью каждой операции дедупликации является src_length байт в файловом дескрипторе dest_fd со смещением logical_offset. Поле reserved должно быть равно нулю.На момент вызова src_fd должен быть открыт на чтение и, dest_fd должен быть открыт на запись. Сумма размеров структуры file_dedupe_range и массива структур file_dedupe_range_info не должна превышать системный размер страницы. Максимальный размер src_length зависит от файловой системы и, обычно равен 16 МиБ. Это ограничение будет невидимо соблюдаться файловой системой. По соглашению, хранилище, используемое src_fd, отображается в dest_fd, а предыдущее содержимое в dest_fd освобождается.

При успешном выполнении ioctl в bytes_deduped возвращается количество дедуплицированных байт, а в status — код состояния операции дедупликации. Если не совпадает даже один байт из диапазона, то запрос дедупликации будет проигнорирован и status будет присвоено FILE_DEDUPE_RANGE_DIFFERS. При успешном выполнении код status изменяется на FILE_DEDUPE_RANGE_SAME, при ошибке — отрицательное значение кода, или FILE_DEDUPE_RANGE_DIFFERS, если данные не совпадают.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.

ОШИБКИ
Возможные коды ошибок (помимо прочих):

EBADF
    Дескриптор src_fd не открыт на чтение; dest_fd не открыт на запись или открыт только для добавления; файловая система, в которой находится src_fd, не поддерживает дедупликацию.

EINVAL
    Файловая система не поддерживает дедупликацию диапазонов в заданных файлах. Эта ошибка также может возникнуть, если файловый дескриптор представляет устройство, FIFO или сокет. Обычно, для дисковых файловых систем требуются, чтобы аргументы смещения и длины были выровнены по основному размеру блока. В XFS и Btrfs нет поддержки дедупликации перекрывающихся диапазонов в одном и том же файле.

EISDIR
    Один из файлов является каталогом и файловая система не поддерживает диапазоны для каталогов.

ENOMEM
    Ядро не смогло выделить достаточно памяти для выполнения операции или размер dest_count слишком большой из-за того, что описание входного аргумента занимает больше одной страницы в памяти.

EOPNOTSUPP
    Может возникать, если файловая система не поддерживает дедупликацию для файловых дескрипторов или когда файловый дескриптор ссылается на специальные иноды.

EPERM
    Дескриптор dest_fd является неизменным.

ETXTBSY
    Один из файлов является файлом подкачки. Файлы подкачки не могут содержаться в совместных хранилищах.

EXDEV
    Дескрипторы dest_fd и src_fd находятся на разных смонтированных файловых системах.

ВЕРСИИ
Данная операция ioctl появилась в Linux 4.5. Раньше она называлась BTRFS_IOC_FILE_EXTENT_SAME и работала только в Btrfs.

СООТВЕТСТВИЕ СТАНДАРТАМ
Данный программный интерфейс существует только в Linux.

ЗАМЕЧАНИЯ
Так как для операции копирования-при-записи требуется выделение нового пространства в хранилище, операция fallocate(2) может отменить совместное использование общих блоков для гарантии того, что последующие операции записи не завершатся ошибкой из-за нехватки места на диске.

Некоторые файловые системы имеют ограничение на количество данных, которое может быть дедуплицировано за один вызов.

СМОТРИТЕ ТАКЖЕ
ioctl(2)