fallocate(2)

НАИМЕНОВАНИЕ
fallocate - управление пространством файла

БИБЛИОТЕКА
Стандартная библиотека языка C (libc, -lc)

ОБЗОР
#define _GNU_SOURCE             /* Смотрите feature_test_macros(7) */
#include <fcntl.h>

int fallocate(int fd, int mode, off_t offset, off_t size);

ОПИСАНИЕ
Это непереносимый системный вызов, существующий только в Linux. В POSIX.1 есть переносимый метод, обеспечивающий выделение пространства под файл (смотрите posix_fallocate(3)).

fallocate() allows the caller to directly manipulate the allocated disk space for the file referred to by fd for the byte range starting at offset and continuing for size bytes.

В аргументе mode задаётся операция, выполняемая над указанным диапазоном. Детали о поддерживаемых операциях представлены в подразделах далее.

  Выделение дискового пространства
The default operation (i.e., mode is zero) of fallocate() allocates the disk space within the range specified by offset and size. The file size (as reported by stat(2)) will be changed if offset+size is greater than the file size. Any subregion within the range specified by offset and size that did not contain data before the call will be initialized to zero. This default behavior closely resembles the behavior of the posix_fallocate(3) library function, and is intended as a method of optimally implementing that function.

After a successful call, subsequent writes into the range specified by offset and size are guaranteed not to fail because of lack of disk space.

If the FALLOC_FL_KEEP_SIZE flag is specified in mode, the behavior of the call is similar, but the file size will not be changed even if offset+size is greater than the file size. Preallocating zeroed blocks beyond the end of the file in this manner is useful for optimizing append workloads.

Если в modeуказан флаг FALLOC_FL_UNSHARE_RANGE, то общие файловые extent-данные будут сделаны частными для файла, чтобы гарантировать, что последующая запись не завершится ошибкой из-за нехватки места. Обычно, это выполняется с помощью операции копирования при записи для всех общих данных файла. Данный флаг может поддерживаться не во всех файловых системах.

Так как выделение выполняется кусками размером с блок, fallocate() может выделить больший диапазон дискового пространства, чем было указано.

  Освобождение файлового пространства
Specifying the FALLOC_FL_PUNCH_HOLE flag (available since Linux 2.6.38) in mode deallocates space (i.e., creates a hole) in the byte range starting at offset and continuing for size bytes. Within the specified range, partial filesystem blocks are zeroed, and whole filesystem blocks are removed from the file. After a successful call, subsequent reads from this range will return zeros.

Флаг FALLOC_FL_PUNCH_HOLE должен быть логически добавлен к флагу FALLOC_FL_KEEP_SIZE в mode; другими словами, даже когда пробивание (punching) выходит за конец файла, размер файла (получаемый с помощью stat(2)) остаётся неизменным.

Не все файловые системы поддерживают FALLOC_FL_PUNCH_HOLE; если файловая система не поддерживает эту операцию, то возвращается ошибка. Операция поддерживается, как минимум, следующими файловыми системами:

•   XFS (начиная с Linux 2.6.38)

•   ext4 (начиная с Linux 3.0)

•   Btrfs (начиная с Linux 3.7)

•   tmpfs(5) (начиная с Linux 3.5)

•   gfs2(5) (начиная с Linux 4.16)

  Сворачивание (Collapsing) файлового пространства
Specifying the FALLOC_FL_COLLAPSE_RANGE flag (available since Linux 3.15) in mode removes a byte range from a file, without leaving a hole. The byte range to be collapsed starts at offset and continues for size bytes. At the completion of the operation, the contents of the file starting at the location offset+size will be appended at the location offset, and the file will be size bytes smaller.

A filesystem may place limitations on the granularity of the operation, in order to ensure efficient implementation. Typically, offset and size must be a multiple of the filesystem logical block size, which varies according to the filesystem type and configuration. If a filesystem has such a requirement, fallocate() fails with the error EINVAL if this requirement is violated.

If the region specified by offset plus size reaches or passes the end of file, an error is returned; instead, use ftruncate(2) to truncate a file.

Вместе с FALLOC_FL_COLLAPSE_RANGE другие флаги в mode указывать нельзя.

В Linux 3.15 флаг FALLOC_FL_COLLAPSE_RANGE поддерживается в ext4 (только для файлов на основе extent) и XFS.

  Зануление файлового пространства
Specifying the FALLOC_FL_ZERO_RANGE flag (available since Linux 3.15) in mode zeros space in the byte range starting at offset and continuing for size bytes. Within the specified range, blocks are preallocated for the regions that span the holes in the file. After a successful call, subsequent reads from this range will return zeros.

Зануление, желательно, выполнять внутри файловой системы, преобразуя диапазон в незаписываемые extents. Этот подход означает, что указанный диапазон на устройстве в действительности не будет содержать нули на физическом уровне (за исключением неполных блоков в одном из концов диапазона), и ввод-вывод требуется только для обновления метаданных.

If the FALLOC_FL_KEEP_SIZE flag is additionally specified in mode, the behavior of the call is similar, but the file size will not be changed even if offset+size is greater than the file size. This behavior is the same as when preallocating space with FALLOC_FL_KEEP_SIZE specified.

Не все файловые системы поддерживают FALLOC_FL_ZERO_RANGE; если файловая система не поддерживает эту операцию, то возвращается ошибка. Операция поддерживается, как минимум, следующими файловыми системами:

•   XFS (начиная с Linux 3.15)

•   ext4, для файлов на основе extent (начиная с Linux 3.15)

•   SMB3 (начиная с Linux 3.17)

•   Btrfs (начиная с Linux 4.16)

  Увеличение файлового пространства
Specifying the FALLOC_FL_INSERT_RANGE flag (available since Linux 4.1) in mode increases the file space by inserting a hole within the file size without overwriting any existing data. The hole will start at offset and continue for size bytes. When inserting the hole inside file, the contents of the file starting at offset will be shifted upward (i.e., to a higher file offset) by size bytes. Inserting a hole inside a file increases the file size by size bytes.

Данный режим имеет те же ограничения что и FALLOC_FL_COLLAPSE_RANGE, независимо от детализации операции Если требования детализации не удовлетворяются, то fallocate() завершается ошибкой EINVAL. Если offset больше или равно концу файла, то возвращается ошибка. Для таких операций (т. е., вставка дыры в конец файла) нужно использовать ftruncate(2).

Вместе с FALLOC_FL_INSERT_RANGE другие флаги в mode указывать нельзя.

Для работы FALLOC_FL_INSERT_RANGE требуется поддержка в файловой системе; сейчас это XFS (начиная с Linux 4.1) и ext4 (начиная с Linux 4.2).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении fallocate() возвращается 0; при ошибке возвращается -1, а в errno содержится код ошибки.

ОШИБКИ

EBADF
    fd не является допустимым файловым дескриптором или не открыт на запись.

EFBIG
    offset+size exceeds the maximum file size.

EFBIG
    В mode указан FALLOC_FL_INSERT_RANGE, и текущий размер файла+len превышает максимальный файловый размер.

EINTR
    При выполнении поступил сигнал; смотрите signal(7).

EINVAL
    offset was less than 0, or size was less than or equal to 0.

EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE and the range specified by offset plus size reaches or passes the end of the file.

EINVAL
    Значение mode равно FALLOC_FL_INSERT_RANGE, но диапазон, указанный в offset, достиг или перешагнул за конец файла.

EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE, but either offset or size is not a multiple of the filesystem block size.

EINVAL
    Значение mode содержит FALLOC_FL_COLLAPSE_RANGE или FALLOC_FL_INSERT_RANGE, а также другие флаги; но с FALLOC_FL_COLLAPSE_RANGE или FALLOC_FL_INSERT_RANGE другие флаги указывать нельзя.

EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE, FALLOC_FL_ZERO_RANGE, or FALLOC_FL_INSERT_RANGE, but the file referred to by fd is not a regular file.

EIO При чтении или записи в файловую систему произошла ошибка ввода-вывода.

ENODEV
    Значение fd не указывает на обычный файл или каталог (если fd — канал или FIFO, то возникнет другая ошибка).

ENOSPC
    Недостаточно дискового пространства на устройстве, на котором расположен файл, указанный в fd.

ENOSYS
    В данном ядре вызов fallocate() не реализован.

EOPNOTSUPP
    Файловая система с файлом, на который указывает fd, не поддерживает данную операцию; или значение mode не поддерживается файловой системой, в которой находится файл, на который указывает fd.

EPERM
    Файл, на который указывает fd, помечен как неизменяемый (immutable) (смотрите chattr(1)).

EPERM
    mode specifies FALLOC_FL_PUNCH_HOLE, FALLOC_FL_COLLAPSE_RANGE, or FALLOC_FL_INSERT_RANGE and the file referred to by fd is marked append-only (see chattr(1)).

EPERM
    Выполнение операции предотвращено опечатыванием (file seal); смотрите fcntl(2).

ESPIPE
    Значение fd указывает на канал или FIFO.

ETXTBSY
    Значение mode равно FALLOC_FL_COLLAPSE_RANGE или FALLOC_FL_INSERT_RANGE, но файл, на который указывает fd, в данный момент выполняется.

СТАНДАРТЫ
Linux.

ИСТОРИЯ

fallocate()
    Linux 2.6.23, glibc 2.10.

FALLOC_FL_*
    glibc 2.18.

СМОТРИТЕ ТАКЖЕ
fallocate(1), ftruncate(2), posix_fadvise(3), posix_fallocate(3)

ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков (<debian-l10n-russian@lists.debian.org>).