From: "Zi Yan" <ziy@nvidia.com>
To: "Zhang Yi" <yi.zhang@huaweicloud.com>, <linux-mm@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-ext4@vger.kernel.org>, <akpm@linux-foundation.org>,
<david@kernel.org>, <ljs@kernel.org>, <liam@infradead.org>,
<vbabka@kernel.org>, <rppt@kernel.org>, <surenb@google.com>,
<mhocko@suse.com>, <hughd@google.com>,
<baolin.wang@linux.alibaba.com>, <willy@infradead.org>,
<jack@suse.cz>, <bfoster@redhat.com>, <joannelkoong@gmail.com>,
<djwong@kernel.org>, <yi.zhang@huawei.com>,
<yizhang089@gmail.com>, <yangerkun@huawei.com>,
<chengzhihao1@huawei.com>, <wangkefeng.wang@huawei.com>,
<yukuai@fnnas.com>
Subject: Re: [PATCH v4 1/4] mm/truncate: align truncation boundaries to mapping minimum folio order
Date: Tue, 22 Sep 2026 11:29:17 -0400 [thread overview]
Message-ID: <DLLYA97QG5ES.P4FF23PGA3MQ@nvidia.com> (raw)
In-Reply-To: <20260922110703.468389-2-yi.zhang@huaweicloud.com>
On Tue Sep 22, 2026 at 7:07 AM EDT, Zhang Yi wrote:
> From: Zhang Yi <yi.zhang@huawei.com>
>
> When the mapping has a non-zero minimum folio order (min_order),
> folio_split() in truncate_inode_partial_folio() stops at min_order
> instead of order 0, so the sub-folio containing a split point stays
> aligned to 1 << min_order rather than to a single page. The original
> boundaries in truncate_inode_pages_range() were based on page
> granularity, so either boundary could land inside the min_order chunk at
> its edge, and the truncation loop would drop that whole chunk, valid
> out-of-range tail included.
>
> For example, a 64K (order-4) folio with min_order = 2 (16K) punched from
> offset 0 to 36K:
>
> split @p0 -> [p0-p3, p4-p7, p8-p15] # non-uniform, min_order
> folio2 = p8-p15 # straddles: p8 in range, p9-p15 tail valid
> 2nd split of folio2 -> [p8-p11, p12-p15] # success
> end(old) = p9 # BUG: p9 inside [p8-p11]
> loop truncates ... p8-p11 # p9-p11's valid tail is lost
>
> It has gone unnoticed so far for two reasons. A non-zero min_order is
> only used by filesystems with a block or sector size larger than the
> page size, and those either always write back the affected range before
> punching a hole or truncating, or they carry filesystem private data on
> dirty folios (e.g. buffer_head), which makes filemap_release_folio()
> fail and folio_split() abort with -EBUSY, so the folio is never split
> and the old start/end boundaries remain valid. The bug only becomes
> reachable on paths that truncate dirty large folios without prior
> writeback and without filesystem private data, such as the upcoming ext4
> iomap buffered I/O path.
>
> Align both start (rounded up) and end (rounded down) to the mapping
> minimum folio order so they always fall on a folio boundary.
>
> Reported-by: Joanne Koong <joannelkoong@gmail.com>
> Link: https://lore.kernel.org/linux-mm/CAJnrk1bQYUe6+1ryyJur5EEnZYrC+_5AYsy=OWzVRgD4202y1g@mail.gmail.com/
> Fixes: e220917fa5077 ("mm: split a folio in minimum folio order chunks")
> Suggested-by: Zi Yan <ziy@nvidia.com>
> Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
> ---
> mm/truncate.c | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
LGTM. Just a nit below.
Reviewed-by: Zi Yan <ziy@nvidia.com>
>
> diff --git a/mm/truncate.c b/mm/truncate.c
> index b58ba940be47..f9625bb4916f 100644
> --- a/mm/truncate.c
> +++ b/mm/truncate.c
> @@ -345,9 +345,11 @@ long mapping_evict_folio(struct address_space *mapping, struct folio *folio)
> * @lstart: offset from which to truncate
> * @lend: offset to which to truncate (inclusive)
> *
> - * Truncate the page cache, removing the pages that are between
> - * specified offsets (and zeroing out partial pages
> - * if lstart or lend + 1 is not page aligned).
> + * Truncate the page cache, removing the folios that are between specified
> + * offsets (and zeroing out partial folios if lstart or lend + 1 is not
> + * folio aligned). For mappings with a non-zero minimum folio order, the
> + * boundaries are aligned inwards to 1 << min_order so the edge sub-folio
> + * straddling the range is kept.
> *
> * Truncate takes two passes - the first pass is nonblocking. It will not
> * block on page locks and it will not block on writeback. The second pass
> @@ -374,14 +376,14 @@ void truncate_inode_pages_range(struct address_space *mapping,
> int i;
> struct folio *folio;
> bool same_folio;
> + pgoff_t min_nrpages = mapping_min_folio_nrpages(mapping);
>
It is better to put it at the top (reverse christmas tree).
--
Best Regards,
Yan, Zi
next prev parent reply other threads:[~2026-09-22 15:29 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 11:06 [PATCH v4 0/4] mm/truncate: fix data loss when truncating straddling large folios Zhang Yi
2026-09-22 11:07 ` [PATCH v4 1/4] mm/truncate: align truncation boundaries to mapping minimum folio order Zhang Yi
2026-09-22 11:27 ` sashiko-bot
2026-09-22 11:32 ` Jan Kara
2026-09-22 15:29 ` Zi Yan [this message]
2026-09-23 8:26 ` Zhang Yi
2026-09-24 9:31 ` Zhang Yi
2026-09-24 10:31 ` Jan Kara
2026-09-22 11:07 ` [PATCH v4 2/4] mm/truncate: look up the end-edge straddler by index Zhang Yi
2026-09-22 11:23 ` sashiko-bot
2026-09-22 11:35 ` Jan Kara
2026-09-22 15:30 ` Zi Yan
2026-09-22 11:07 ` [PATCH v4 3/4] mm/truncate: fix data loss when splitting straddling large folios fails Zhang Yi
2026-09-22 11:23 ` sashiko-bot
2026-09-22 11:44 ` Jan Kara
2026-09-22 16:58 ` Zi Yan
2026-09-22 17:27 ` Zi Yan
2026-09-23 8:29 ` Zhang Yi
2026-09-22 11:07 ` [PATCH v4 4/4] mm/truncate: clarify return value of truncate_inode_partial_folio() Zhang Yi
2026-09-22 11:29 ` sashiko-bot
2026-09-22 11:58 ` Jan Kara
2026-09-23 13:29 ` Zhang Yi
2026-09-22 17:28 ` Zi Yan
2026-09-22 13:47 ` [PATCH v4 0/4] mm/truncate: fix data loss when truncating straddling large folios Brian Foster
2026-09-23 13:31 ` 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=DLLYA97QG5ES.P4FF23PGA3MQ@nvidia.com \
--to=ziy@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=bfoster@redhat.com \
--cc=chengzhihao1@huawei.com \
--cc=david@kernel.org \
--cc=djwong@kernel.org \
--cc=hughd@google.com \
--cc=jack@suse.cz \
--cc=joannelkoong@gmail.com \
--cc=liam@infradead.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=rppt@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=wangkefeng.wang@huawei.com \
--cc=willy@infradead.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.