From: Zhang Yi <yizhang089@gmail.com>
To: sashiko-reviews@lists.linux.dev, Zhang Yi <yi.zhang@huaweicloud.com>
Cc: linux-ext4@vger.kernel.org, tytso@mit.edu
Subject: Re: [PATCH v7 27/31] ext4: set DISKSIZE_GROW_PENDING after zeroing unaligned EOF block
Date: Sat, 10 Oct 2026 15:21:04 +0800 [thread overview]
Message-ID: <7208fed8-d3e8-454c-9376-a359f9089400@gmail.com> (raw)
In-Reply-To: <sashiko-outbox-165360@kernel.org>
On 10/9/2026 7:21 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] ext4: torn lockless read of i_disksize causes missing DISKSIZE_GROW_PENDING
> --
>
> commit 4a76a3a815e11b477d4aaf7fd5a0eb69623ddb31
> Author: Zhang Yi <yi.zhang@huawei.com>
>
> ext4: set DISKSIZE_GROW_PENDING after zeroing unaligned EOF block
>
> This commit adds the ext4_iomap_mark_disksize_pending() function to set
> EXT4_STATE_DISKSIZE_GROW_PENDING after zeroing an unaligned EOF block.
> It ensures that the zeroed block is written before any subsequent data
> updates i_disksize, preventing the exposure of stale data.
>
>> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
>> index 9b6916609000c..3bdb5f3b119ab 100644
>> --- a/fs/ext4/inode.c
>> +++ b/fs/ext4/inode.c
>> @@ -4847,6 +4847,89 @@ static int ext4_block_zero_range(struct inode *inode,
>
> [ ... ]
>
>> + /*
>> + * If the zeroed range does not overlap the existing on-disk tail
>> + * block, the zeroed data lies beyond the currently on-disk data
>> + * and will be written back before i_disksize is advanced past it,
>> + * so no stale data can be exposed.
>> + *
>> + * Checking i_disksize here (after folio_wait_writeback()) is
>> + * necessary and safe. If a delalloc writeback of this folio was
>> + * in-flight, it could be raced by a concurrent mmap write which
>> + * corrupts the tail block beyond i_size but the i_disksize is not
>> + * advanced. folio_wait_writeback() has waited for its completion
>> + * and the ioend has advanced i_disksize accordingly. If writeback
>> + * had not started, we don't need to mark any pending state because
>> + * any future writeback will carry the pagecache content that now
>> + * includes the zeroed data, so no stale data can appear on disk
>> + * even without the pending tracking.
>> + */
>> + if (from >= round_up(READ_ONCE(EXT4_I(inode)->i_disksize),
>> + i_blocksize(inode)))
>> + goto out;
>
> [Severity: Medium]
> Could this lockless read of a 64-bit integer suffer from a torn read on
> 32-bit architectures?
>
> On a 32-bit system, READ_ONCE() on a 64-bit variable like i_disksize compiles
> to two 32-bit loads. If a concurrent thread updates i_disksize via
> WRITE_ONCE() (for example, during I/O completion while holding i_data_sem)
> and the value crosses a 32-bit boundary, this read can tear.
>
> For instance, if i_disksize changes from 0x00000000_FFFFFFFF to
> 0x00000001_00000000, the torn read could yield 0x00000000_00000000.
>
> This would cause the condition to evaluate to true, skipping the pending
> tracking and failing to set EXT4_STATE_DISKSIZE_GROW_PENDING.
>
> If the system crashes, this could allow i_disksize to be advanced past the
> unwritten zeroed block, exposing stale, uninitialized disk data to the
> file tail and defeating the data-ordering mechanism.
>
> While i_size is protected by i_size_seqcount on 32-bit platforms, i_disksize
> does not seem to have seqcount protection here.
>
I don't think a torn read is possible here, because there is no
concurrent writer of i_disksize in this window.
ext4_iomap_mark_disksize_pending() is called under i_rwsem, so the
i_disksize read can only be raced by the worker in
ext4_iomap_wb_update_disksize(). But it cannot make i_disksize larger
than what we account for here. It writes min(end, i_size), and all
callers of ext4_block_zero_eof() zero the tail block before i_size is
advanced, so the new value is at most 'from'. To change the outcome of
the check, 'end' would have to fall inside the block containing 'from',
and the only ioend that can do that is the one covering the folio we
have already waited for with folio_wait_writeback(). So the value we
read is already settled.
Thanks,
Yi.
next prev parent reply other threads:[~2026-10-10 7:21 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 10:30 [PATCH v7 00/31] ext4: use iomap for regular file's buffered I/O path Zhang Yi
2026-10-09 10:30 ` [PATCH v7 01/31] ext4: simplify size updating in ext4_setattr() Zhang Yi
2026-10-09 10:51 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 02/31] ext4: factor out ext4_truncate_[up|down]() Zhang Yi
2026-10-09 10:54 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 03/31] ext4: set EXT4_MAP_NEW flag for delayed allocated blocks Zhang Yi
2026-10-09 10:50 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 04/31] ext4: recheck extent status tree before block allocation Zhang Yi
2026-10-09 10:54 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 05/31] ext4: fix orig_mlen initialization in ext4_map_blocks() Zhang Yi
2026-10-09 10:53 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 06/31] ext4: allow ext4_map_blocks() to start its own transaction handle Zhang Yi
2026-10-09 10:58 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 07/31] ext4: avoid unnecessary transaction in ext4_map_blocks() for unwritten extents Zhang Yi
2026-10-09 10:53 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 08/31] ext4: skip block allocation for holes in the data submission path Zhang Yi
2026-10-09 10:58 ` sashiko-bot
2026-10-10 0:55 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 09/31] ext4: add iomap address space operations for buffered I/O Zhang Yi
2026-10-09 10:54 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 10/31] ext4: implement buffered read path using iomap Zhang Yi
2026-10-09 11:07 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 11/31] ext4: pass out extent seq counter when mapping da blocks Zhang Yi
2026-10-09 10:55 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 12/31] ext4: do not use data=ordered mode for inodes using buffered iomap path Zhang Yi
2026-10-09 11:01 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 13/31] ext4: implement buffered write path using iomap Zhang Yi
2026-10-09 11:03 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 14/31] ext4: rework handle credit accounting for unwritten extent conversion Zhang Yi
2026-10-09 11:20 ` sashiko-bot
2026-10-10 2:33 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 15/31] ext4: implement writeback path using iomap Zhang Yi
2026-10-09 11:13 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 16/31] ext4: implement mmap " Zhang Yi
2026-10-09 11:10 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 17/31] ext4: implement partial block zero range " Zhang Yi
2026-10-09 11:09 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 18/31] ext4: drain writeback before removing extents on the iomap path Zhang Yi
2026-10-09 11:06 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 19/31] ext4: add block mapping tracepoints for iomap buffered I/O path Zhang Yi
2026-10-09 11:03 ` sashiko-bot
2026-10-10 3:04 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 20/31] ext4: disable online defrag when inode using " Zhang Yi
2026-10-09 11:00 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 21/31] ext4: add EXT4_STATE_DISKSIZE_GROW_PENDING state bit and helpers Zhang Yi
2026-10-09 11:04 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 22/31] ext4: submit and wait for pending disksize-grow I/O on writeback Zhang Yi
2026-10-09 11:18 ` sashiko-bot
2026-10-10 3:11 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 23/31] ext4: advance i_disksize to i_size upon disksize-grow I/O completion Zhang Yi
2026-10-09 11:19 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 24/31] ext4: defer i_disksize update while DISKSIZE_GROW_PENDING is set Zhang Yi
2026-10-09 11:21 ` sashiko-bot
2026-10-10 3:35 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 25/31] ext4: submit and wait for disksize-grow I/O in fallocate paths Zhang Yi
2026-10-09 11:25 ` sashiko-bot
2026-10-09 10:30 ` [PATCH v7 26/31] ext4: clear DISKSIZE_GROW_PENDING on truncate or error Zhang Yi
2026-10-09 11:16 ` sashiko-bot
2026-10-10 4:59 ` Zhang Yi
2026-10-09 10:30 ` [PATCH v7 27/31] ext4: set DISKSIZE_GROW_PENDING after zeroing unaligned EOF block Zhang Yi
2026-10-09 11:21 ` sashiko-bot
2026-10-10 7:21 ` Zhang Yi [this message]
2026-10-10 9:00 ` Ojaswin Mujoo
2026-10-10 9:50 ` Zhang Yi
2026-10-10 13:49 ` Ojaswin Mujoo
2026-10-10 15:54 ` Zhang Yi
2026-10-11 9:30 ` Ojaswin Mujoo
2026-10-09 10:30 ` [PATCH v7 28/31] ext4: add tracepoints for DISKSIZE_GROW_PENDING set, clear, and wait Zhang Yi
2026-10-09 11:13 ` sashiko-bot
2026-10-09 10:38 ` [PATCH v7 29/31] ext4: add tracepoints for EOF block zeroing and disksize-grow I/O Zhang Yi
2026-10-09 11:16 ` sashiko-bot
2026-10-09 10:38 ` [PATCH v7 30/31] ext4: partially enable iomap for the buffered I/O path of regular files Zhang Yi
2026-10-09 11:33 ` sashiko-bot
2026-10-10 8:09 ` Zhang Yi
2026-10-09 10:38 ` [PATCH v7 31/31] ext4: introduce a mount option for iomap buffered I/O path Zhang Yi
2026-10-09 11:17 ` sashiko-bot
2026-10-09 17:54 ` [syzbot ci] Re: ext4: use iomap for regular file's " syzbot ci
2026-10-10 8:44 ` Zhang Yi
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=7208fed8-d3e8-454c-9376-a359f9089400@gmail.com \
--to=yizhang089@gmail.com \
--cc=linux-ext4@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tytso@mit.edu \
--cc=yi.zhang@huaweicloud.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