mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Baokun Li <libaokun1@huawei.com>
To: Jan Kara <jack@suse.cz>
Cc: Zhang Yi <yi.zhang@huaweicloud.com>, <linux-ext4@vger.kernel.org>,
	<linux-fsdevel@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<tytso@mit.edu>, <adilger.kernel@dilger.ca>,
	<ojaswin@linux.ibm.com>, <ritesh.list@gmail.com>,
	<hch@infradead.org>, <djwong@kernel.org>,
	Zhang Yi <yi.zhang@huawei.com>, <yizhang089@gmail.com>,
	<yangerkun@huawei.com>, <yukuai@fnnas.com>, <libaokun9@gmail.com>,
	<libaokun9@gmail.com>
Subject: Re: [PATCH -next v2 03/22] ext4: only order data when partially block truncating down
Date: Fri, 6 Feb 2026 09:14:53 +0800	[thread overview]
Message-ID: <6b3fddd2-047b-4639-b54f-554b16a0ef36@huawei.com> (raw)
In-Reply-To: <s434ifpengcthkmohmc6vvmvppx4o2k2ctk2p3it55ncgce3je@irbt7xpdnnzu>

On 2026-02-05 22:07, Jan Kara wrote:
> On Thu 05-02-26 11:27:09, Baokun Li wrote:
>> On 2026-02-04 22:18, Jan Kara wrote:
>>> Hi Zhang!
>>>
>>> On Wed 04-02-26 14:42:46, Zhang Yi wrote:
>>>> On 2/3/2026 5:59 PM, Jan Kara wrote:
>>>>> On Tue 03-02-26 14:25:03, Zhang Yi wrote:
>>>>>> Currently, __ext4_block_zero_page_range() is called in the following
>>>>>> four cases to zero out the data in partial blocks:
>>>>>>
>>>>>> 1. Truncate down.
>>>>>> 2. Truncate up.
>>>>>> 3. Perform block allocation (e.g., fallocate) or append writes across a
>>>>>>    range extending beyond the end of the file (EOF).
>>>>>> 4. Partial block punch hole.
>>>>>>
>>>>>> If the default ordered data mode is used, __ext4_block_zero_page_range()
>>>>>> will write back the zeroed data to the disk through the order mode after
>>>>>> zeroing out.
>>>>>>
>>>>>> Among the cases 1,2 and 3 described above, only case 1 actually requires
>>>>>> this ordered write. Assuming no one intentionally bypasses the file
>>>>>> system to write directly to the disk. When performing a truncate down
>>>>>> operation, ensuring that the data beyond the EOF is zeroed out before
>>>>>> updating i_disksize is sufficient to prevent old data from being exposed
>>>>>> when the file is later extended. In other words, as long as the on-disk
>>>>>> data in case 1 can be properly zeroed out, only the data in memory needs
>>>>>> to be zeroed out in cases 2 and 3, without requiring ordered data.
>>>>> Hum, I'm not sure this is correct. The tail block of the file is not
>>>>> necessarily zeroed out beyond EOF (as mmap writes can race with page
>>>>> writeback and modify the tail block contents beyond EOF before we really
>>>>> submit it to the device). Thus after this commit if you truncate up, just
>>>>> zero out the newly exposed contents in the page cache and dirty it, then
>>>>> the transaction with the i_disksize update commits (I see nothing
>>>>> preventing it) and then you crash, you can observe file with the new size
>>>>> but non-zero content in the newly exposed area. Am I missing something?
>>>>>
>>>> Well, I think you are right! I missed the mmap write race condition that
>>>> happens during the writeback submitting I/O. Thank you a lot for pointing
>>>> this out. I thought of two possible solutions:
>>>>
>>>> 1. We also add explicit writeback operations to the truncate-up and
>>>>    post-EOF append writes. This solution is the most straightforward but
>>>>    may cause some performance overhead. However, since at most only one
>>>>    block is written, the impact is likely limited. Additionally, I
>>>>    observed that the implementation of the XFS file system also adopts a
>>>>    similar approach in its truncate up and down operation. (But it is
>>>>    somewhat strange that XFS also appears to have the same issue with
>>>>    post-EOF append writes; it only zero out the partial block in
>>>>    xfs_file_write_checks(), but it neither explicitly writeback zeroed
>>>>    data nor employs any other mechanism to ensure that the zero data
>>>>    writebacks before the metadata is written to disk.)
>>>>
>>>> 2. Resolve this race condition, ensure that there are no non-zero data
>>>>    in the post-EOF partial blocks on the disk. I observed that after the
>>>>    writeback holds the folio lock and calls folio_clear_dirty_for_io(),
>>>>    mmap writes will re-trigger the page fault. Perhaps we can filter out
>>>>    the EOF folio based on i_size in ext4_page_mkwrite(),
>>>>    block_page_mkwrite() and iomap_page_mkwrite(), and then call
>>>>    folio_wait_writeback() to wait for this partial folio writeback to
>>>>    complete. This seems can break the race condition without introducing
>>>>    too much overhead (no?).
>>>>
>>>> What do you think? Any other suggestions are also welcome.
>>> Hum, I like the option 2 because IMO non-zero data beyond EOF is a
>>> corner-case quirk which unnecessarily complicates rather common paths. But
>>> I'm not sure we can easily get rid of it. It can happen for example when
>>> you do appending write inside a block. The page is written back but before
>>> the transaction with i_disksize update commits we crash. Then again we have
>>> a non-zero content inside the block beyond EOF.
>>>
>>> So the only realistic option I see is to ensure tail of the block gets
>>> zeroed on disk before the transaction with i_disksize update commits in the
>>> cases of truncate up or write beyond EOF. data=ordered mode machinery is an
>>> asynchronous way how to achieve this. We could also just synchronously
>>> writeback the block where needed but the latency hit of such operation is
>>> going to be significant so I'm quite sure some workload somewhere will
>>> notice although the truncate up / write beyond EOF operations triggering this
>>> are not too common. So why do you need to get rid of these data=ordered
>>> mode usages? I guess because with iomap keeping our transaction handle ->
>>> folio lock ordering is complicated? Last time I looked it seemed still
>>> possible to keep it though.
>>>
>>> Another possibility would be to just *submit* the write synchronously and
>>> use data=ordered mode machinery only to wait for IO to complete before the
>>> transaction commits. That way it should be safe to start a transaction
>>> while holding folio lock and thus the iomap conversion would be easier.
>>>
>>> 								Honza
>> Can we treat EOF blocks as metadata and update them in the same
>> transaction as i_disksize? Although this would introduce some
>> management and journaling overhead, it could avoid the deadlock
>> of "writeback -> start handle -> trigger writeback".
> No, IMHO that would get too difficult. Just look at the hoops data=journal
> mode has to jump through to make page cache handling work with the
> journalling machinery. And you'd now have that for all the inodes. So I
> think some form of data=ordered machinery is much simpler to reason about.
>
> 								Honza

Indeed, this is a bit tricky.


Regards,
Baokun


  reply	other threads:[~2026-02-06  1:15 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-03  6:25 [PATCH -next v2 00/22] ext4: use iomap for regular file's buffered I/O path Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 01/22] ext4: make ext4_block_zero_page_range() pass out did_zero Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 02/22] ext4: make ext4_block_truncate_page() return zeroed length Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 03/22] ext4: only order data when partially block truncating down Zhang Yi
2026-02-03  9:59   ` Jan Kara
2026-02-04  6:42     ` Zhang Yi
2026-02-04 14:18       ` Jan Kara
2026-02-05  3:27         ` Baokun Li
2026-02-05 14:07           ` Jan Kara
2026-02-06  1:14             ` Baokun Li [this message]
2026-02-05  7:50         ` Zhang Yi
2026-02-05 15:05           ` Jan Kara
2026-02-06 11:09             ` Zhang Yi
2026-02-06 15:35               ` Jan Kara
2026-02-09  8:28                 ` Zhang Yi
2026-02-10 12:02                   ` Zhang Yi
2026-02-10 14:07                     ` Jan Kara
2026-02-10 16:11                       ` Zhang Yi
2026-02-11 11:42                         ` Jan Kara
2026-02-11 13:38                           ` Zhang Yi
2026-02-04  4:21   ` kernel test robot
2026-02-10  7:05   ` Ojaswin Mujoo
2026-02-10 15:57     ` Zhang Yi
2026-02-11 15:23       ` Ojaswin Mujoo
2026-02-03  6:25 ` [PATCH -next v2 04/22] ext4: factor out journalled block zeroing range Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 05/22] ext4: stop passing handle to ext4_journalled_block_zero_range() Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 06/22] ext4: don't zero partial block under an active handle when truncating down Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 07/22] ext4: move ext4_block_zero_page_range() out of an active handle Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 08/22] ext4: zero post EOF partial block before appending write Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 09/22] ext4: add a new iomap aops for regular file's buffered IO path Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 10/22] ext4: implement buffered read iomap path Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 11/22] ext4: pass out extent seq counter when mapping da blocks Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 12/22] ext4: implement buffered write iomap path Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 13/22] ext4: implement writeback " Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 14/22] ext4: implement mmap " Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 15/22] iomap: correct the range of a partial dirty clear Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 16/22] iomap: support invalidating partial folios Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 17/22] ext4: implement partial block zero range iomap path Zhang Yi
2026-02-04  0:21   ` kernel test robot
2026-02-03  6:25 ` [PATCH -next v2 18/22] ext4: do not order data for inodes using buffered " Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 19/22] ext4: add block mapping tracepoints for iomap buffered I/O path Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 20/22] ext4: disable online defrag when inode using " Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 21/22] ext4: partially enable iomap for the buffered I/O path of regular files Zhang Yi
2026-02-03  6:25 ` [PATCH -next v2 22/22] ext4: introduce a mount option for iomap buffered I/O path Zhang Yi
2026-02-03  6:43 ` [PATCH -next v2 00/22] ext4: use iomap for regular file's " Christoph Hellwig
2026-02-03  9:18   ` Zhang Yi
2026-02-03 13:14     ` Theodore Tso
2026-02-04  1:33       ` Zhang Yi
2026-02-04  1:59       ` Baokun Li
2026-02-04 14:23         ` Jan Kara
2026-02-05  2:06           ` Zhang Yi
2026-02-05  3:04             ` Baokun Li
2026-02-05 12:58             ` Jan Kara
2026-02-06  2:15               ` Zhang Yi
2026-02-05  2:55           ` Baokun Li
2026-02-05 12:46             ` Jan Kara

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=6b3fddd2-047b-4639-b54f-554b16a0ef36@huawei.com \
    --to=libaokun1@huawei.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=djwong@kernel.org \
    --cc=hch@infradead.org \
    --cc=jack@suse.cz \
    --cc=libaokun9@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojaswin@linux.ibm.com \
    --cc=ritesh.list@gmail.com \
    --cc=tytso@mit.edu \
    --cc=yangerkun@huawei.com \
    --cc=yi.zhang@huawei.com \
    --cc=yi.zhang@huaweicloud.com \
    --cc=yizhang089@gmail.com \
    --cc=yukuai@fnnas.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

all inboxes | Powered by JetHome®