]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ext4: don't order data when zeroing unwritten or delayed block
authorZhang Yi <yi.zhang@huawei.com>
Tue, 23 Dec 2025 01:19:27 +0000 (09:19 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 20 Jan 2026 03:22:32 +0000 (22:22 -0500)
When zeroing out a written partial block, it is necessary to order the
data to prevent exposing stale data on disk. However, if the buffer is
unwritten or delayed, it is not allocated as written, so ordering the
data is not required. This can prevent strange and unnecessary ordered
writes when appending data across a region within a block.

Assume we have a 2K unwritten file on a filesystem with 4K blocksize,
and buffered write from 3K to 4K. Before this patch,
__ext4_block_zero_page_range() would add the range [2k,3k) to the
ordered range, and then the JBD2 commit process would write back this
block. However, it does nothing since the block is not mapped as
written, this folio will be redirtied and written back agian through the
normal write back process.

Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Baokun Li <libaokun1@huawei.com>
Link: https://patch.msgid.link/20251223011927.34042-1-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/inode.c

index 08a7f2b54a9e1cf70f5837d28f8a7f01d443c54b..6ad1a6e3d1338e884a2483ca6aa9efbcf5a0e7c9 100644 (file)
@@ -4133,9 +4133,13 @@ static int __ext4_block_zero_page_range(handle_t *handle,
        if (ext4_should_journal_data(inode)) {
                err = ext4_dirty_journalled_data(handle, bh);
        } else {
-               err = 0;
                mark_buffer_dirty(bh);
-               if (ext4_should_order_data(inode))
+               /*
+                * Only the written block requires ordered data to prevent
+                * exposing stale data.
+                */
+               if (!buffer_unwritten(bh) && !buffer_delay(bh) &&
+                   ext4_should_order_data(inode))
                        err = ext4_jbd2_inode_add_write(handle, inode, from,
                                        length);
        }