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
| Name | What 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_SIZE | Allocate extents but do not change st_size. Reads past the original EOF still return zero bytes. |
| FALLOC_FL_PUNCH_HOLELinux 3.5 | Free 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.15 | Physically 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.15 | Zero 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.1 | Insert a hole of len bytes at offset, shifting existing data forward. File grows by len. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EOPNOTSUPP | The filesystem does not support the requested mode. |
| EINVAL | offset or len are negative; mode combination is invalid; or offset/len not block-aligned for COLLAPSE_RANGE or INSERT_RANGE. |
| EBADF | fd is not open for writing. |
| ESPIPE | fd 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 holeTrimmed 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
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
