From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Zhang Yi <yi.zhang@huawei.com>, Jan Kara <jack@suse.cz>,
Theodore Ts'o <tytso@mit.edu>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 7.1.y 1/2] ext4: track partial-zero outcome per edge in ext4_zero_partial_blocks()
Date: Tue, 25 Aug 2026 20:50:04 -0400 [thread overview]
Message-ID: <20260826005005.830778-1-sashal@kernel.org> (raw)
In-Reply-To: <2026082417-smokiness-hacker-071d@gregkh>
From: Zhang Yi <yi.zhang@huawei.com>
[ Upstream commit 4c1f6931395ad026415cbdb924ffc240f86eb557 ]
Replace the single bool did_zero output of ext4_zero_partial_blocks()
with a bitmask that records which edge (start, end, or both in the
single-block case) was actually partial-zeroed. This allows callers to
distinguish which edges have been zeroed, preparing for unaligned
FALLOC_FL_WRITE_ZEROES handling in later patches.
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260714080044.4038124-7-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: a5179156ac1d ("ext4: zero out whole block for clean edges in WRITE_ZEROES")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/ext4.h | 5 ++++-
fs/ext4/extents.c | 2 +-
fs/ext4/inode.c | 36 ++++++++++++++++++++++++++++++------
3 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6569d1d575a01..bc25746c8b726 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3119,8 +3119,11 @@ extern int ext4_chunk_trans_extent(struct inode *inode, int nrblocks);
extern int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
int pextents);
extern int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end);
+
+#define EXT4_PARTIAL_ZERO_START 0x1
+#define EXT4_PARTIAL_ZERO_END 0x2
extern int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart,
- loff_t length, bool *did_zero);
+ loff_t length, unsigned int *partial_zeroed);
extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern int ext4_get_projid(struct inode *inode, kprojid_t *projid);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 125f628e738ab..c68feb1697090 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4715,7 +4715,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
loff_t align_start, align_end, new_size = 0;
loff_t end = offset + len;
unsigned int blocksize = i_blocksize(inode);
- bool partial_zeroed = false;
+ unsigned int partial_zeroed = 0;
int ret, flags;
trace_ext4_zero_range(inode, offset, len, mode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4fce9ec176f88..ea0b2359ca0cb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4253,13 +4253,26 @@ int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end)
return 0;
}
+/*
+ * Zero out the unaligned head and tail of the [lstart, lstart+length)
+ * range.
+ *
+ * On return, @partial_zeroed records which edges actually got
+ * partial-zeroed. Set EXT4_PARTIAL_ZERO_START/EXT4_PARTIAL_ZERO_END if
+ * the head/tail block got actually partially zeroed (in written, dirty
+ * unwritten or delalloc state). Cleared if the head/tail block is a
+ * hole or a clean unwritten block, in which case there is nothing that
+ * needs zeroing. When the head and tail land in the same block, both
+ * bits are set together on a successful zeroing.
+ */
int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t length,
- bool *did_zero)
+ unsigned int *partial_zeroed)
{
struct super_block *sb = inode->i_sb;
unsigned partial_start, partial_end;
ext4_fsblk_t start, end;
loff_t byte_end = (lstart + length - 1);
+ bool did_zero = false;
int err = 0;
partial_start = lstart & (sb->s_blocksize - 1);
@@ -4271,21 +4284,32 @@ int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t length,
/* Handle partial zero within the single block */
if (start == end &&
(partial_start || (partial_end != sb->s_blocksize - 1))) {
- err = ext4_block_zero_range(inode, lstart, length, did_zero,
+ err = ext4_block_zero_range(inode, lstart, length, &did_zero,
NULL);
+ if (did_zero)
+ *partial_zeroed |= (EXT4_PARTIAL_ZERO_START |
+ EXT4_PARTIAL_ZERO_END);
return err;
}
/* Handle partial zero out on the start of the range */
if (partial_start) {
err = ext4_block_zero_range(inode, lstart, sb->s_blocksize,
- did_zero, NULL);
+ &did_zero, NULL);
if (err)
return err;
+ if (did_zero)
+ *partial_zeroed |= EXT4_PARTIAL_ZERO_START;
}
/* Handle partial zero out on the end of the range */
- if (partial_end != sb->s_blocksize - 1)
+ if (partial_end != sb->s_blocksize - 1) {
+ did_zero = false;
err = ext4_block_zero_range(inode, byte_end - partial_end,
- partial_end + 1, did_zero, NULL);
+ partial_end + 1, &did_zero, NULL);
+ if (err)
+ return err;
+ if (did_zero)
+ *partial_zeroed |= EXT4_PARTIAL_ZERO_END;
+ }
return err;
}
@@ -4434,7 +4458,7 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t end = offset + length;
handle_t *handle;
unsigned int credits;
- bool partial_zeroed = false;
+ unsigned int partial_zeroed = 0;
int ret;
trace_ext4_punch_hole(inode, offset, length, 0);
--
2.53.0
next prev parent reply other threads:[~2026-08-26 0:50 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 12:29 FAILED: patch "[PATCH] ext4: zero out whole block for clean edges in WRITE_ZEROES" failed to apply to 7.1-stable tree gregkh
2026-08-26 0:50 ` Sasha Levin [this message]
2026-08-26 0:50 ` [PATCH 7.1.y 2/2] ext4: zero out whole block for clean edges in WRITE_ZEROES Sasha Levin
2026-08-26 1:17 ` [PATCH 7.1.y 1/2] ext4: track partial-zero outcome per edge in ext4_zero_partial_blocks() Sasha Levin
2026-08-26 1:17 ` [PATCH 7.1.y 2/2] ext4: zero out whole block for clean edges in WRITE_ZEROES Sasha Levin
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=20260826005005.830778-1-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=jack@suse.cz \
--cc=stable@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox