[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260203062523.3869120-7-yi.zhang@huawei.com>
Date: Tue, 3 Feb 2026 14:25:06 +0800
From: Zhang Yi <yi.zhang@...wei.com>
To: linux-ext4@...r.kernel.org
Cc: linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org,
tytso@....edu,
adilger.kernel@...ger.ca,
jack@...e.cz,
ojaswin@...ux.ibm.com,
ritesh.list@...il.com,
hch@...radead.org,
djwong@...nel.org,
yi.zhang@...wei.com,
yi.zhang@...weicloud.com,
yizhang089@...il.com,
libaokun1@...wei.com,
yangerkun@...wei.com,
yukuai@...as.com
Subject: [PATCH -next v2 06/22] ext4: don't zero partial block under an active handle when truncating down
When truncating down, move the call to ext4_block_truncate_page() before
starting the handle. This change has no effect in non-journal data mode
because it doesn't require an active handle. However, in journal data
mode, it may cause the zeroing of partial blocks and the release of
subsequent full blocks to be distributed across different transactions.
This is safe as well because the transaction that zeroes the blocks will
always be committed first, and the entire truncate operation does not
require atomicity guarantee.
This change prepares for converting the block zero range to the iomap
infrastructure, which does not use ordered data mode and requires active
writeback to prevent exposing stale data. The writeback must be
completed before the transaction to remove the orphan is committed, and
it cannot be performed within an active handle.
Signed-off-by: Zhang Yi <yi.zhang@...wei.com>
---
fs/ext4/inode.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c05b1c0a1b45..e67c750866a5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4570,7 +4570,7 @@ int ext4_inode_attach_jinode(struct inode *inode)
int ext4_truncate(struct inode *inode)
{
struct ext4_inode_info *ei = EXT4_I(inode);
- unsigned int credits;
+ unsigned int credits, zero_len = 0;
int err = 0, err2;
handle_t *handle;
struct address_space *mapping = inode->i_mapping;
@@ -4603,6 +4603,12 @@ int ext4_truncate(struct inode *inode)
err = ext4_inode_attach_jinode(inode);
if (err)
goto out_trace;
+
+ zero_len = ext4_block_truncate_page(mapping, inode->i_size);
+ if (zero_len < 0) {
+ err = zero_len;
+ goto out_trace;
+ }
}
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
@@ -4616,21 +4622,12 @@ int ext4_truncate(struct inode *inode)
goto out_trace;
}
- if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
- unsigned int zero_len;
-
- zero_len = ext4_block_truncate_page(mapping, inode->i_size);
- if (zero_len < 0) {
- err = zero_len;
+ /* Ordered zeroed data to prevent exposure of stale data. */
+ if (zero_len && !IS_DAX(inode) && ext4_should_order_data(inode)) {
+ err = ext4_jbd2_inode_add_write(handle, inode, inode->i_size,
+ zero_len);
+ if (err)
goto out_stop;
- }
- if (zero_len && !IS_DAX(inode) &&
- ext4_should_order_data(inode)) {
- err = ext4_jbd2_inode_add_write(handle, inode,
- inode->i_size, zero_len);
- if (err)
- goto out_stop;
- }
}
/*
--
2.52.0
Powered by blists - more mailing lists