名称

fallocate-操作文件空间

FALLOCATE - Linux手册页

Linux程序员手册 第2部分
更新日期: 2019-11-19

版本

从内核2.6.23开始,fallocate()在Linux上可用。从版本2.10开始,glibc提供了支持。仅从2.18版开始,才在glibc标头中定义FALLOC_FL_ *标志。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

语法

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <fcntl.h>

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

遵循规范

fallocate()是特定于Linux的。

返回值

成功时,fallocate()返回零。发生错误时,将返回-1并将errno设置为指示错误。

另外参见

fallocate(1),ftruncate(2),posix_fadvise(3),posix_fallocate(3)

说明

这是特定于Linux的不可移植的系统调用。有关确保为文件分配空间的POSIX.1指定的可移植方法,请参见posix_fallocate(3)。

fallocate()允许调用方直接为fd引用的文件操作文件分配的磁盘空间,该文件空间的字节范围从offset开始并持续len个字节。

mode参数确定要在给定范围上执行的操作。下面的小节中提供了支持的操作的详细信息。

Allocating disk space

fallocate()的默认操作(即mode为零)在offset和len指定的范围内分配磁盘空间。如果offset + len大于文件大小,则将更改文件大小(由stat(2)报告)。在offset和len指定的范围内,在调用之前不包含数据的任何子区域都将初始化为零。此默认行为与posix_fallocate(3)库函数的行为非常相似,旨在作为最佳实现该函数的方法。

调用成功后,由于磁盘空间不足,可以保证后续写入offset和len指定的范围不会失败。

如果在模式下指定了FALLOC_FL_KEEP_SIZE标志,则调用的行为类似,但是即使offset + len大于文件大小,文件大小也不会改变。以这种方式在文件末尾预分配零块对于优化附加工作负载很有用。

如果在模式下指定了FALLOC_FL_UNSHARE标志,则共享文件数据范围将对文件私有,以确保后续的写入不会因空间不足而失败。通常,这将通过对文件中的所有共享数据执行写时复制操作来完成。并非所有文件系统都支持此标志。

因为分配是在块大小的块中完成的,所以fallocate()可能分配比指定更大的磁盘空间范围。

Deallocating file space

在模式下指定FALLOC_FL_PUNCH_HOLE标志(自Linux 2.6.38起可用)在字节范围内从偏移量开始分配空间(即创建一个空位),并以len字节继续。在指定范围内,部分文件系统块被清零,并且整个文件系统块从文件中删除。成功调用后,此范围内的后续读取将返回零。

FALLOC_FL_PUNCH_HOLE标志必须与FALLOC_FL_KEEP_SIZE在模式下进行或运算;换句话说,即使删除文件的末尾,文件大小(由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 file space

在模式下指定FALLOC_FL_COLLAPSE_RANGE标志(从Linux 3.15开始可用)可从文件中删除字节范围,而不会留下漏洞。要折叠的字节范围从偏移量开始,并持续len个字节。操作完成后,将从位置offset + len开始的文件内容附加到位置offset,并且文件将小len个字节。

文件系统可能会限制操作的粒度,以确保有效实施。通常,offset和len必须是文件系统逻辑块大小的倍数,该大小根据文件系统类型和配置而变化。如果文件系统有这样的要求,则如果违反了该要求,fallocate()将失败并显示错误EINVAL。

如果由offset加len指定的区域到达或超过了文件末尾,则返回错误;否则,将返回错误。而是使用ftruncate(2)截断文件。

不能与FALLOC_FL_COLLAPSE_RANGE一起在模式中指定其他标志。

从Linux 3.15开始,ext4(仅适用于基于扩展数据的文件)和XFS支持FALLOC_FL_COLLAPSE_RANGE。

Zeroing file space

在模式零下指定FALLOC_FL_ZERO_RANGE标志(从Linux 3.15开始可用),将字节范围的空间从偏移量开始,一直到len个字节。在指定范围内,将为跨越文件中孔的区域预分配块。成功调用后,此范围内的后续读取将返回零。

最好通过将范围转换为未写入的范围来在文件系统内完成调零。这种方法意味着指定的范围不会在设备上被物理清零(范围两端的部分块除外),并且(否则)仅需要I / O来更新元数据。

如果在模式下另外指定了FALLOC_FL_KEEP_SIZE标志,则调用的行为类似,但是即使offset + len大于文件大小,文件大小也不会改变。此行为与在指定FALLOC_FL_KEEP_SIZE的情况下预分配空间时相同。

并非所有文件系统都支持FALLOC_FL_ZERO_RANGE;如果文件系统不支持该操作,则返回错误。至少在以下文件系统上支持该操作:

*
XFS(从Linux 3.15开始)
*
ext4,用于基于扩展数据的文件(自Linux 3.15开始)
*
SMB3(从Linux 3.17开始)
*
Btrfs(从Linux 4.16开始)

Increasing file space

在模式下指定FALLOC_FL_INSERT_RANGE标志(从Linux 4.1开始可用)可以通过在文件大小内插入一个空洞而不覆盖任何现有数据来增加文件空间。孔将从偏移量开始,并持续len个字节。当在文件内插入孔时,从偏移量开始的文件内容将向上移位(即,移至较高的文件偏移量)len个字节。在文件内部插入孔会使文件大小增加len个字节。

关于操作的粒度,此模式与FALLOC_FL_COLLAPSE_RANGE具有相同的限制。如果不满足粒度要求,则fallocate()失败,并显示错误EINVAL。如果偏移量等于或大于文件末尾,则返回错误。对于此类操作(即在文件末尾插入孔),应使用ftruncate(2)。

不能与FALLOC_FL_INSERT_RANGE一起在模式中指定其他标志。

FALLOC_FL_INSERT_RANGE需要文件系统支持。支持此操作的文件系统包括XFS(自Linux 4.1起)和ext4(自Linux 4.2起)。

错误说明

EBADF
fd不是有效的文件描述符,或者未打开以进行写入。
EFBIG
offset + len超过最大文件大小。
EFBIG
模式为FALLOC_FL_INSERT_RANGE,并且当前文件大小+ len超过了最大文件大小。
EINTR
执行期间捕获到信号;参见signal(7)。
EINVAL
offset小于0,或len小于或等于0。
EINVAL
模式为FALLOC_FL_COLLAPSE_RANGE,偏移量加上len指定的范围达到或超过文件的末尾。
EINVAL
模式为FALLOC_FL_INSERT_RANGE,偏移量指定的范围达到或超过文件的末尾。
EINVAL
模式是FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_INSERT_RANGE,但是offset或len不是文件系统块大小的倍数。
EINVAL
模式包含FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_INSERT_RANGE之一以及其他标志; FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_INSERT_RANGE不允许使用其他标志。
EINVAL
模式是FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_ZERO_RANGE或FALLOC_FL_INSERT_RANGE,但是fd引用的文件不是常规文件。
EIO
从文件系统读取或写入文件系统时发生I / O错误。
ENODEV
fd不引用常规文件或目录。 (如果fd是管道或FIFO,则会导致不同的错误。)
ENOSPC
设备上没有足够的空间包含fd所引用的文件。
ENOSYS
该内核不实现fallocate()。
EOPNOTSUPP
包含fd引用的文件的文件系统不支持此操作;或包含fd所引用文件的文件系统不支持该模式。
EPERM
fd引用的文件标记为不可变(请参见chattr(1))。
EPERM
模式指定FALLOC_FL_PUNCH_HOLE或FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_INSERT_RANGE,并且fd引用的文件标记为仅附加(请参见chattr(1))。
EPERM
该操作被文件封条阻止;参见fcntl(2)。
ESPIPE
fd是指管道或FIFO。
ETXTBSY
模式指定FALLOC_FL_COLLAPSE_RANGE或FALLOC_FL_INSERT_RANGE,但是fd引用的文件当前正在执行。
日期:2019-08-20 17:58:39 来源:oir作者:oir