From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Alexey Kuznetsov <kuznet@virtuozzo.com>
Cc: "Denis V. Lunev" <den@virtuozzo.com>, devel@openvz.org
Subject: [Devel] [PATCH vz10] fs: move FALLOC_FL_PREALLOCATE to a bit upstream has not taken
Date: Tue, 08 Sep 2026 15:38:18 +0200 [thread overview]
Message-ID: <20260908-pr-khorenko-vstor-144521-falloc_fl_preallocate-v1-1-f14f74322d0c@virtuozzo.com> (raw)
We had FALLOC_FL_PREALLOCATE == 0x80.
Upstream commit 7bd43cc79cab ("fs: introduce FALLOC_FL_WRITE_ZEROES to
fallocate"), released in v6.17, gives 0x80 to a mode of its own and
adds it to FALLOC_FL_MODE_MASK.
Move the mode to 0x00100000, well above the range upstream allocates
modes from and away from the top of the word, where a future user is
just as likely to start.
The number cannot simply change, though, because userspace carries its
own copy of it. Export the value as a read-only ext4 module parameter,
/sys/module/ext4/parameters/falloc_fl_preallocate, and let userspace
read the mode from there.
The old value stays accepted as FALLOC_FL_PREALLOCATE_OLD, so that
userspace built before this change keeps working. It has to be dropped
before the rebase onto v6.17 or later, otherwise we would take
FALLOC_FL_WRITE_ZEROES requests for our own mode.
Feature: ext4: preallocation flag for small fallocates
https://virtuozzo.atlassian.net/browse/VSTOR-144521
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
Follow-up to the v3 thread of "fs/ext4: let FALLOC_FL_PREALLOCATE
through the vfs_fallocate mode switch": 0x80 is FALLOC_FL_WRITE_ZEROES
upstream since v6.17, so our mode has to move before we rebase onto it,
and the value has to become discoverable instead of hardcoded on both
sides.
---
fs/ext4/extents.c | 14 ++++++++++----
fs/open.c | 1 +
include/linux/falloc.h | 3 ++-
include/uapi/linux/falloc.h | 15 ++++++++++++++-
4 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 38f50770f6585..eca3f0312ac53 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -39,6 +39,10 @@ static unsigned int falloc_prealloc;
module_param(falloc_prealloc, uint, 0644);
MODULE_PARM_DESC(falloc_prealloc, "Preallocate fallocate like it is a write for smaller sizes");
+static unsigned int falloc_fl_preallocate = FALLOC_FL_PREALLOCATE;
+module_param(falloc_fl_preallocate, uint, 0444);
+MODULE_PARM_DESC(falloc_fl_preallocate, "fallocate() mode value asking for preallocation");
+
/*
* used by extent splitting.
*/
@@ -4514,8 +4518,8 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
* that it doesn't get unnecessarily split into multiple
* extents.
*/
- if (!(mode & FALLOC_FL_PREALLOCATE) && len <= EXT_UNWRITTEN_MAX_LEN &&
- len > falloc_prealloc)
+ if (!(mode & (FALLOC_FL_PREALLOCATE | FALLOC_FL_PREALLOCATE_OLD)) &&
+ len <= EXT_UNWRITTEN_MAX_LEN && len > falloc_prealloc)
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
/*
@@ -4754,7 +4758,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
/* Return error if mode is not supported */
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE |
- FALLOC_FL_INSERT_RANGE | FALLOC_FL_PREALLOCATE))
+ FALLOC_FL_INSERT_RANGE | FALLOC_FL_PREALLOCATE |
+ FALLOC_FL_PREALLOCATE_OLD))
return -EOPNOTSUPP;
inode_lock(inode);
@@ -4770,7 +4775,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
goto out_inode_lock;
if ((mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_ALLOCATE_RANGE ||
- (mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_PREALLOCATE) {
+ (mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_PREALLOCATE ||
+ (mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_PREALLOCATE_OLD) {
ret = ext4_do_fallocate(file, offset, len, mode);
goto out_inode_lock;
}
diff --git a/fs/open.c b/fs/open.c
index fc72ad09e7e81..65c96bf03dc93 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -268,6 +268,7 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
case FALLOC_FL_UNSHARE_RANGE:
case FALLOC_FL_ZERO_RANGE:
case FALLOC_FL_PREALLOCATE:
+ case FALLOC_FL_PREALLOCATE_OLD:
break;
case FALLOC_FL_PUNCH_HOLE:
if (!(mode & FALLOC_FL_KEEP_SIZE))
diff --git a/include/linux/falloc.h b/include/linux/falloc.h
index f6eee099b3fca..58e991ea6771f 100644
--- a/include/linux/falloc.h
+++ b/include/linux/falloc.h
@@ -37,7 +37,8 @@ struct space_resv {
FALLOC_FL_ZERO_RANGE | \
FALLOC_FL_INSERT_RANGE | \
FALLOC_FL_UNSHARE_RANGE | \
- FALLOC_FL_PREALLOCATE)
+ FALLOC_FL_PREALLOCATE | \
+ FALLOC_FL_PREALLOCATE_OLD)
/* on ia32 l_start is on a 32-bit boundary */
#if defined(CONFIG_X86_64)
diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h
index 7ac8ffb8e6523..49aa826ad8f8a 100644
--- a/include/uapi/linux/falloc.h
+++ b/include/uapi/linux/falloc.h
@@ -78,6 +78,19 @@
*/
#define FALLOC_FL_UNSHARE_RANGE 0x40
-#define FALLOC_FL_PREALLOCATE 0x80
+/*
+ * FALLOC_FL_PREALLOCATE tells the filesystem to allocate the range the way a
+ * write would, with mballoc preallocation, rather than trimming the request
+ * down to a single unwritten extent.
+ *
+ * Userspace may read the mode value from
+ * /sys/module/ext4/parameters/falloc_fl_preallocate.
+ *
+ * FALLOC_FL_PREALLOCATE_OLD is the value used before upstream v6.17 claimed
+ * 0x80 for FALLOC_FL_WRITE_ZEROES. It is accepted as an alias of the above,
+ * and has to be dropped before a rebase onto v6.17 or later.
+ */
+#define FALLOC_FL_PREALLOCATE_OLD 0x80
+#define FALLOC_FL_PREALLOCATE 0x00100000
#endif /* _UAPI_FALLOC_H_ */
---
base-commit: 3466ec0b2cdf9d49dbb36d7b5ed9b36dfb2fb04d
change-id: 20260908-pr-khorenko-vstor-144521-falloc_fl_preallocate-cec80ce87000
Best regards,
--
Konstantin Khorenko <khorenko@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next reply other threads:[~2026-09-08 13:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 13:38 Konstantin Khorenko [this message]
2026-09-08 13:43 ` Alexey Kuznetsov
2026-09-08 14:25 ` Konstantin Khorenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260908-pr-khorenko-vstor-144521-falloc_fl_preallocate-v1-1-f14f74322d0c@virtuozzo.com \
--to=khorenko@virtuozzo.com \
--cc=den@virtuozzo.com \
--cc=devel@openvz.org \
--cc=kuznet@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.