[Devel] [PATCH vz10 v3] fs/ext4: let FALLOC_FL_PREALLOCATE through the vfs_fallocate mode switch
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Sep 7 17:10:09 MSK 2026
From: Alexey Kuznetsov <kuznet at virtuozzo.com>
Upstream commit 57413d8e172c ("fs: sort out the fallocate mode vs flag
mess") replaced the FALLOC_FL_SUPPORTED_MASK check in vfs_fallocate()
with a switch over FALLOC_FL_MODE_MASK that rejects unlisted modes with
EOPNOTSUPP, and ext4_fallocate() got a dedicated ALLOCATE_RANGE path.
The vz10 port of FALLOC_FL_PREALLOCATE only added the bit to the mask,
so fallocate(FALLOC_FL_PREALLOCATE) fails with EOPNOTSUPP before it
reaches ext4, and vstorage falls back to the slow path, which halves
its write performance.
Accept the mode in vfs_fallocate() and route it to ext4_do_fallocate()
together with plain allocation; ext4_alloc_file_blocks() already
honours the flag.
The falloc_prealloc description in the commit being fixed has the two
middle cases inverted and states its sizes in bytes where the code
counts blocks. Corrected:
khorenko@: logic is the following:
if FALLOC_FL_PREALLOCATE
preallocation enabled for all "len"
if !FALLOC_FL_PREALLOCATE
if len <= falloc_prealloc
preallocation enabled
if falloc_prealloc < len <= EXT_UNWRITTEN_MAX_LEN
preallocation disabled
if len > EXT_UNWRITTEN_MAX_LEN
preallocation enabled
So if FALLOC_FL_PREALLOCATE is used, fallocate() behaves like write(),
i.e. always uses preallocation, the falloc_prealloc value is ignored.
If FALLOC_FL_PREALLOCATE is NOT used:
- stock fallocate() disables preallocation for len sizes
<= EXT_UNWRITTEN_MAX_LEN, that is 32767 blocks.
- introduced falloc_prealloc allows to make an experiment:
if we set non-zero falloc_prealloc parameter (in blocks),
preallocation will be disabled for sizes
falloc_prealloc .. EXT_UNWRITTEN_MAX_LEN.
The idea behind: if you perform a small fallocate, you probably do
not mean to fragment the file.
Fixes: 275be8b96ddf ("fs/ext4: introduce FALLOC_FL_PREALLOCATE flag to fallocate")
https://virtuozzo.atlassian.net/browse/VSTOR-142784
Signed-off-by: Alexey Kuznetsov <kuznet at virtuozzo.com>
Feature: ext4: preallocation flag for small fallocates
---
v2 -> v3: commit message enhanced
---
fs/ext4/extents.c | 3 ++-
fs/open.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index b771cb594c061..38f50770f6585 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4769,7 +4769,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
if (ret)
goto out_inode_lock;
- if ((mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_ALLOCATE_RANGE) {
+ if ((mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_ALLOCATE_RANGE ||
+ (mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_PREALLOCATE) {
ret = ext4_do_fallocate(file, offset, len, mode);
goto out_inode_lock;
}
diff --git a/fs/open.c b/fs/open.c
index 91f4785b89f3c..fc72ad09e7e81 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -267,6 +267,7 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
case FALLOC_FL_ALLOCATE_RANGE:
case FALLOC_FL_UNSHARE_RANGE:
case FALLOC_FL_ZERO_RANGE:
+ case FALLOC_FL_PREALLOCATE:
break;
case FALLOC_FL_PUNCH_HOLE:
if (!(mode & FALLOC_FL_KEEP_SIZE))
--
2.43.0
More information about the Devel
mailing list