fallocate -
управление
пространством
файла
Standard C library (
libc,
-lc)
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */
#include <fcntl.h>
int fallocate(int fd, int mode, off_t offset, off_t len);
Это
непереносимый
системный
вызов,
существующий
только в Linux. В
POSIX.1 есть
переносимый
метод,
обеспечивающий
выделение
пространства
под файл
(смотрите
posix_fallocate(3)).
Вызов
fallocate()
позволяет
вызывающему
напрямую
управлять
выделением
дискового
пространства
под файл, на
который
указывает
fd, для
байтового
диапазона,
начинающегося
с
offset и
имеющего
длину
len
байт.
В
аргументе
mode задаётся
операция,
выполняемая
над
указанным
диапазоном.
Детали о
поддерживаемых
операциях
представлены
в
подразделах
далее.
По
умолчанию
(т. е.
значение
mode
равно нулю)
fallocate()
выделяет
место на
диске в
диапазоне,
задаваемом
offset и
len.
Размер
файла
(получаемый
через
stat(2))
будет
изменён,
если
offset+
len
больше чем
размер
файла.
Любая
подобласть
внутри
диапазона,
заданного
offset и
len,
которая не
содержала
данных до
вызова,
будет
заполнена
нулями.
Такое
поведение
по
умолчанию
очень
напоминает
поведение
библиотечной
функции
posix_fallocate(3), и было
введено
для
оптимальной
реализации
этой
функции.
После
успешного
выполнения
вызова
последующие
операции
записи в
диапазон,
указанный
offset и
len,
гарантированно
не
завершатся
с ошибкой
из-за
нехватки
места на
диске.
Если в
mode
указан
флаг
FALLOC_FL_KEEP_SIZE, то
поведение
по
умолчанию
почти то же,
но размер
файла не
будет
изменён
даже, если
offset+
len больше
чем размер
файла. Это
полезно
для
предварительного
выделения
блоков с
нулями за
концом
файла для
оптимизации
загруженности
при
добавлении.
Если в
modeуказан
флаг
FALLOC_FL_UNSHARE_RANGE,
то общие
файловые
extent-данные
будут
сделаны
частными
для файла,
чтобы
гарантировать,
что
последующая
запись не
завершится
ошибкой
из-за
нехватки
места.
Обычно, это
выполняется
с помощью
операции
копирования
при записи
для всех
общих
данных
файла.
Данный
флаг может
поддерживаться
не во всех
файловых
системах.
Так как
выделение
выполняется
кусками
размером с
блок,
fallocate()
может
выделить
больший
диапазон
дискового
пространства,
чем было
указано.
Указание
флага
FALLOC_FL_PUNCH_HOLE
(доступен,
начиная с Linux
2.6.38) в
mode
освобождает
пространство
(т.е., создаёт
дыру) в
диапазоне
начиная с
offset и до
len
байт.
Внутри
заданного
диапазона
неполные
блоки
файловой
системы
заполняются
нулями, а
полные
блоки
файловой
системы
удаляются
из файла.
После
успешного
выполнения
вызова,
последующие
операции
чтения из
этого
диапазона
вернут
нули.
Флаг
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)
Задание
флага
FALLOC_FL_COLLAPSE_RANGE
(доступен,
начиная с Linux 3.15)
в
mode
приводит к
удалению
байтового
диапазона
из файла
без
создания
дыры.
Сворачиваемый
диапазон
байт
начинается
с
offset и
длится
len
байт. По
завершению
операции,
содержимое
файла,
начиная с
offset+len, будет
добавлено
в
расположение
offset, и файл
будет на
len
байт
меньше.
У файловой
системы
могут быть
ограничения
на
детализацию
операции,
для
большей
эффективности
реализации.
Обычно,
значения
offset
и
len должны
быть
кратны
размеру
логического
блока
файловой
системы,
различающемуся
в разных
файловых
системах и
зависящему
от
настроек.
Если
файловая
система
содержит
такое
требование
и оно
нарушено,
то
fallocate()
завершается
ошибкой
EINVAL.
Если
область,
заданная
offset
плюс
len
достигает
или
выходит за
конец
файла, то
возвращается
ошибка;
вместо
этого
используйте
ftruncate(2) для
обрезания
файла.
Вместе с
FALLOC_FL_COLLAPSE_RANGE
другие
флаги в
mode
указывать
нельзя.
В Linux 3.15 флаг
FALLOC_FL_COLLAPSE_RANGE
поддерживается
в ext4 (только
для файлов
на основе extent)
и XFS.
Задание
флага
FALLOC_FL_ZERO_RANGE
(доступен,
начиная с Linux 3.15)
в
mode
приводит к
обнулению
байтового
диапазона,
начиная с
offset и
размером
len
байт.
Внутри
указанного
диапазона
блоки
выделяются
заранее
для
областей,
которые
попадают в
дыры в
файле.
После
успешного
выполнения
вызова
последующие
операции
чтения из
этого
диапазона
будут
возвращать
нули.
Зануление,
желательно,
выполнять
внутри
файловой
системы,
преобразуя
диапазон в
незаписываемые
extents. Этот
подход
означает,
что
указанный
диапазон
на
устройстве
в
действительности
не будет
содержать
нули на
физическом
уровне (за
исключением
неполных
блоков в
одном из
концов
диапазона),
и
ввод-вывод
требуется
только для
обновления
метаданных.
Если в
mode
также
указан
флаг
FALLOC_FL_KEEP_SIZE, то
поведение
вызова
похоже, но
размер
файла не
будет
изменён
даже, если
offset+
len больше
размера
файла.
Такое
поведение
совпадает
с
предварительным
выделением
пространства
с помощью
указания
флага
FALLOC_FL_KEEP_SIZE.
Не все
файловые
системы
поддерживают
FALLOC_FL_ZERO_RANGE; если
файловая
система не
поддерживает
эту
операцию,
то
возвращается
ошибка.
Операция
поддерживается,
как
минимум,
следующими
файловыми
системами:
- •
- XFS
(начиная с Linux
3.15)
- •
- ext4, для
файлов на
основе extent
(начиная с Linux
3.15)
- •
- SMB3
(начиная с Linux
3.17)
- •
- Btrfs
(начиная с Linux
4.16)
Задание
флага
FALLOC_FL_INSERT_RANGE
(доступен
начиная с Linux 4.1)
в
mode
увеличивает
файловое
пространство
посредством
вставки
дыры (hole) в
размер
файла без
перезаписывания
существующих
данных.
Дыра
начинается
с
offset и
продолжается
len байт. При
вставки
дыры
внутрь
файла
содержимое
файла,
начинающееся
с
offset, будет
сдвинуто
вперёд (т. е.,
станет
доступно
по
большему
смещению в
файле) на
len
байт.
Вставка
дыры
внутрь
файла
увеличивает
размер
файла на
len
байт.
Данный
режим
имеет те же
ограничения
что и
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+len
превышает
максимальный
размер
файла.
- EFBIG
- В mode
указан
FALLOC_FL_INSERT_RANGE, и
текущий
размер
файла+ len
превышает
максимальный
файловый
размер.
- EINTR
- При
выполнении
поступил
сигнал;
смотрите
signal(7).
- EINVAL
- Значение
offset меньше 0,
или len
меньше или
равно 0.
- EINVAL
- Значение
mode равно
FALLOC_FL_COLLAPSE_RANGE, но
диапазон,
указанный
в offset плюс len,
достиг или
перешагнул
за конец
файла.
- EINVAL
- Значение
mode равно
FALLOC_FL_INSERT_RANGE, но
диапазон,
указанный
в offset, достиг
или
перешагнул
за конец
файла.
- EINVAL
- Значение
mode равно
FALLOC_FL_COLLAPSE_RANGE или
FALLOC_FL_INSERT_RANGE, но
значение
offset или len не
кратно
размеру
блока
файловой
системы.
- 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, в данный
момент
выполняется.
fallocate() is available since Linux 2.6.23. Support is provided since
glibc 2.10. The
FALLOC_FL_* flags are defined in glibc headers only
since glibc 2.18.
Вызов
fallocate()
есть
только в Linux.
fallocate(1),
ftruncate(2),
posix_fadvise(3),
posix_fallocate(3)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitry Bolkhovskikh
<
[email protected]>, Yuri Kozlov <
[email protected]> и
Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]