$RodHat_/search
Syscall reference · Filesystem

fallocate(2)

Allocate disk space, punch holes, collapse or insert byte ranges in a file.

Since
Linux 2.6.23check your kernel →
glibc
fallocate(3) (wraps the syscall directly since glibc 2.10)
System
Linux
Man page
fallocate(2)

Synopsis

#include <fcntl.h>
#include <linux/falloc.h>

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

Rod's take

posix_fallocate(3) silently falls back to write-fill when the filesystem doesn't support native preallocation. A 500GB preallocate that takes an hour and burns all your write I/O is usually this. Use fallocate(2) directly: it returns EOPNOTSUPP and fails cleanly. FALLOC_FL_PUNCH_HOLE is the lesser-known half of the interface: free blocks in the middle of a file without changing st_size, reads return zeros, disk is returned to the pool. ZFS on Linux ignores preallocation calls (CoW has no concept of 'claim these blocks now') and returns success anyway; punch hole support is version-dependent.

Flags and arguments that matter

NameWhat it does
0 (no flags)Allocate blocks in [offset, offset+len); extend st_size if needed. Returns EOPNOTSUPP if the filesystem does not support native allocation.
FALLOC_FL_KEEP_SIZEAllocate extents but do not change st_size. Reads past the original EOF still return zero bytes.
FALLOC_FL_PUNCH_HOLELinux 3.5Free the blocks in [offset, offset+len); range reads as zeros. Must be combined with FALLOC_FL_KEEP_SIZE. Range is rounded to filesystem block boundaries.
FALLOC_FL_COLLAPSE_RANGELinux 3.15Physically remove [offset, offset+len) from the file, shifting subsequent data. File shrinks by len. Offset and len must be block-aligned.
FALLOC_FL_ZERO_RANGELinux 3.15Zero the byte range without necessarily freeing blocks; may be implemented as a hole punch or as explicit zeroing depending on the filesystem.
FALLOC_FL_INSERT_RANGELinux 4.1Insert a hole of len bytes at offset, shifting existing data forward. File grows by len.

Errors you will actually hit

errnoMeaning
EOPNOTSUPPThe filesystem does not support the requested mode.
EINVALoffset or len are negative; mode combination is invalid; or offset/len not block-aligned for COLLAPSE_RANGE or INSERT_RANGE.
EBADFfd is not open for writing.
ESPIPEfd refers to a pipe or FIFO.

Example

/* preallocate without changing st_size */
fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1 << 30);

/* punch a 128 MiB hole at offset 0, blocks freed, reads as zero */
fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 128 << 20);

/* remove first 64 MiB, shift remaining data down */
fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, 0, 64 << 20);

# shell
fallocate -l 10G bigfile.img                          # preallocate 10 GiB
fallocate --punch-hole --offset 0 --length 128M f     # punch hole

Trimmed from the full walkthrough in fallocate(2): preallocate extents and punch holes without writing zeros.

BSD equivalent

No direct equivalent. posix_fallocate(3) on FreeBSD writes zeros if the filesystem does not support native preallocation.

The long version, from the console

Sources

  1. fallocate(2) Linux man page
  2. Punching holes in files (LWN.net, 2011)

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.