linux手册翻译——fallocate(2)


fallocate - manipulate file space

 #define _GNU_SOURCE             /* See feature_test_macros(7) */
 #include 

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


这是一个不可移植的、特定于 Linux 的系统调用。 For the portable, POSIX.1-specified method of ensuring that space is allocated for a file, see posix_fallocate(3).

fallocate() 允许调用者直接操作fd 引用的文件所分配的磁盘空间,操作的字节范围为[offset,offset+len]。

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

Allocating disk space(文件预留)

fallocate()的默认操作(即mode=0)是在参数offsetlen指定的范围内分配磁盘空间。如果offset+len大于文件的大小,则文件大小将被修改。超过原范围的区域将会被初始化为0。此默认行为与 posix_fallocate(3) 库函数的行为非常相似,是实现 posix_fallocate(3) 的最佳实现方法。
调用成功后,后续写入 offset 和 len 指定的范围不会因为磁盘空间不足而失败。

注:这样做的有什么用呢?根据博客用fallocate进行"文件预留"或"文件打洞",可以有以下好处:
(1)可以让文件尽可能的占用连续的磁盘扇区,减少后续写入和读取文件时的磁盘寻道开销;
(2)迅速占用磁盘空间,防止使用过程中所需空间不足。
(3)后面再追加数据的话,不会需要改变文件大小,所以后面将不涉及metadata的修改

If the FALLOC_FL_UNSHARE_RANGE flag is specified in mode, shared file data extents will be made private to the file to guarantee that a subsequent write will not fail due to lack of space. Typically, this will be done by performing a copy-on-write operation on all shared data in the file. This flag may not be supported by all filesystems.

如果在mode中指定了FALLOC_FL_KEEP_SIZE标志,调用的行为类似,即依然会为文件分配磁盘空间,但是不会修改文件大小。这种预分配的方式可以用来优化文件的append操作,也就是在执行append的时候不需要再额外申请磁盘空间了。

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

由于分配是以块大小的块完成的,fallocate() 可能会分配比指定范围更大的磁盘空间。

** Deallocating file space(文件打洞)**

当mode指定为FALLOC_FL_PUNCH_HOLE时,会释放指定范围内的空间,即创建一个空洞。在指定的范围内,部分的文件块(即文件块部分属于该范围)将会被置为0,全部的在范围内的文件块,将会被从文件系统中删除。成功调用后,后续的读取将会返回0。

FALLOC_FL_PUNCH_HOLE必须和FALLOC_FL_KEEP_SIZE通过或运算一起使用,换句话说,FALLOC_FL_PUNCH_HOLE是不能修改文件的大小的。

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

  • XFS (since Linux 2.6.38)
  • ext4 (since Linux 3.0)
  • Btrfs (since Linux 3.7)
  • tmpfs(5) (since Linux 3.5)
  • gfs2(5) (since Linux 4.16)

Collapsing file space

当mode指定为FALLOC_FL_COLLAPSE_RANGE标志时,将从文件中删除指定的字节范围,而不会留下空洞。操作完成后,从offset+len开始位置的文件内容将会被追加到offset处。文件大小会减少len

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

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

FALLOC_FL_COLLAPSE_RANGE标志和其他标志不兼容。

在 Linux 3.15 中,ext4(only for extent-based files)和 XFS 支持 FALLOC_FL_COLLAPSE_RANGE标志。

Zeroing file space

当mode指定为FALLOC_FL_COLLAPSE_RANGE标志时,将会指定范围内分配磁盘空间,填补空洞。成功调用后后续读取将会返回0。

Zeroing is done within the filesystem preferably by converting the range into unwritten extents. This approach means that the specified range will not be physically zeroed out on the device (except for partial blocks at the either end of the range), and I/O is (otherwise) required only to update metadata.可能的意思是,最好不要将物理磁盘清零,而是配置一个为写入的状态,这样读取上来的pagecache就是0。这种情况下,仅仅需要修改文件元数据就可有了。

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

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

  • XFS
  • ext4
  • SMB3
  • Btrfs

Increasing file space

如果在mode中额外指定了FALLOC_FL_INSERT_RANGE标志,那么将会在offset开始的位置插入一个大小为len的空洞,在不覆盖文件内容的前提下增加文件的空间。

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

FALLOC_FL_INSERT_RANGE标志与其他标志不兼容。

目前只有XFS (since Linux 4.1) 和 ext4 (since Linux 4.2)支持此标志。


n success, fallocate() returns zero. On error, -1 is returned and errno is set to indicate the error.

  • EBADF
    fd is not a valid file descriptor, or is not opened for writing.
  • EFBIG
    offset+len exceeds the maximum file size.
  • EFBIG
    mode is FALLOC_FL_INSERT_RANGE, and the current file size+len exceeds the maximum file size.
  • EINTR
    A signal was caught during execution; see signal(7).
  • EINVAL
    offset was less than 0, or len was less than or equal to 0.
  • EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE and the range specified by offset plus len reaches or passes the end of the file.
  • EINVAL
    mode is FALLOC_FL_INSERT_RANGE and the range specified by offset reaches or passes the end of the file.
  • EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE, but either offset or len is not a multiple of the filesystem block size.
  • EINVAL
    mode contains one of FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE and also other flags; no other flags are permitted with FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE.
  • EINVAL
    mode is FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_ZERO_RANGE or FALLOC_FL_INSERT_RANGE, but the file referred to by fd is not a regular file.
  • EIO
    An I/O error occurred while reading from or writing to a filesystem.
  • ENODEV
    fd does not refer to a regular file or a directory. (If fd is a pipe or FIFO, a different error results.)
  • ENOSPC
    There is not enough space left on the device containing the file referred to by fd.
  • ENOSYS
    This kernel does not implement fallocate().
  • EOPNOTSUPP
    The filesystem containing the file referred to by fd does not support this operation; or the mode is not supported by the filesystem containing the file referred to by fd.
  • EPERM
    The file referred to by fd is marked immutable (see chattr(1)).
  • EPERM
    mode specifies FALLOC_FL_PUNCH_HOLE or FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE and the file referred to by fd is marked append-only (see chattr(1)).
  • EPERM
    The operation was prevented by a file seal; see fcntl(2).
  • ESPIPE
    fd refers to a pipe or FIFO.
  • ETXTBSY
    mode specifies FALLOC_FL_COLLAPSE_RANGE or FALLOC_FL_INSERT_RANGE, but the file referred to by fd is currently being executed.


fallocate() is available on Linux since kernel 2.6.23. Support is provided by glibc since version 2.10. The FALLOC_FL_* flags are defined in glibc headers only since version 2.18.


fallocate() is Linux-specific.

你可能感兴趣的:(linux手册翻译——fallocate(2))