mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v4 0/4] mm/truncate: fix data loss when truncating straddling large folios
@ 2026-09-22 11:06 Zhang Yi
  2026-09-22 11:07 ` [PATCH v4 1/4] mm/truncate: align truncation boundaries to mapping minimum folio order Zhang Yi
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Zhang Yi @ 2026-09-22 11:06 UTC (permalink / raw)
  To: linux-mm
  Cc: linux-fsdevel, linux-kernel, linux-ext4, akpm, david, ljs, liam,
	vbabka, rppt, surenb, mhocko, hughd, baolin.wang, willy, jack,
	ziy, bfoster, joannelkoong, djwong, yi.zhang, yi.zhang,
	yizhang089, yangerkun, chengzhihao1, wangkefeng.wang, yukuai

From: Zhang Yi <yi.zhang@huawei.com>

Hello,

This is the fourth version fixing data loss when truncating straddling
large folios caught on the upcomming ext4 + iomap buffered I/O
conversion.

When truncate_inode_pages_range() punches a hole or truncates a file,
truncate_inode_partial_folio() splits a large folio so that the caller
can drop the in-range sub-folios while keeping the out-of-range tail
intact.  This series fixes three distinct problems in that path that
can each lose the valid out-of-range tail of a straddling folio, plus a
follow-up that clarifies the return value semantics.

Patch 01 aligns the truncation boundaries inwards to the mapping minimum
folio order in truncate_inode_pages_range().  With a non-zero min_order,
folio_split() stops at min_order instead of order 0, so a boundary
computed at page granularity can land inside a min-order-aligned
sub-folio and the truncate loop drops that whole chunk, valid tail
included, causing data loss.

Patch 02 looks the end-edge straddler up by its page index through
__filemap_get_folio() in truncate_inode_partial_folio().  After the
first split the straddler is unlocked and only transiently ref'd in the
page cache, so the page pointer derived from the original folio can be
freed and reallocated as a different folio in the same mapping, and the
mapping check cannot catch it, which may cause incorrect splitting and
potential data loss.

Patch 03 reworks the contract between truncate_inode_partial_folio() and
its callers.  If the second split of the straddler fails, the function
reported success unconditionally, and the leftover incorrect end
position could cause the truncate loop to drop that valid tail.  After
rework, it tells the caller the exact page range safe to discard via new
pstart/pend out-parameters, so the truncate loop never touches a
straddling folio that still holds valid out-of-range data.

Patch 04 clarifies the return value semantics to "at least one split
succeeded", which is all the shmem caller needs to decide whether to
reset its scan loop.


The second patch fixes a pre-existing race issue that is reachable
today, so it is Cc'd to stable.  Patches 01 and 03 require a dirty large
folio that carries no filesystem private data, so they are not reachable
on current filesystems.  They were found while developing the upcoming
ext4 iomap buffered I/O path[1].

Thanks,
Yi.

[1] https://lore.kernel.org/linux-fsdevel/a638a8fb-c184-4069-ae33-379ec12cd514@huaweicloud.com/


v3->v4:
 - Move the patch that fixes data loss when min_order is non-zero to the
   first patch position, aligning start and end in
   truncate_inode_pages_range(). (Zi Yan)
 - Add patch 2, fixing the invalid folio2 issue under concurrency when
   truncate_inode_partial_folio() splits at the end position. Use
   __filemap_get_folio() to obtain a reliable folio2. (Jan Kara)

v2->v3:
 - Rework the folio2 validity check logic to fix the invalid
   folio->index issue. (sashiko)
 - Clarify the pstart and pend setting logic and the corresponding
   comments to make it more readable. (Brian, Joanne)
 - Split the patch into 3 small patches. (Zi Yan)

v1->v2:
 - Export pstart as a new parameter so that the generic and shmem
   truncate paths don't need to recompute the start value from the
   return value. (Brian)
 - When min_order is non-zero, align [pstart, pend] to the inner
   boundaries of the folio to ensure they do not point into the middle
   of a large folio, which could otherwise cause valid data within the
   folio to be incorrectly cleared. (Joanne)

v3: https://lore.kernel.org/linux-mm/20260916092450.654408-1-yi.zhang@huaweicloud.com/
v2: https://lore.kernel.org/linux-mm/20260909062339.473816-1-yi.zhang@huaweicloud.com/
v1: https://lore.kernel.org/linux-mm/20260903115018.2034541-1-yi.zhang@huaweicloud.com/


Zhang Yi (4):
  mm/truncate: align truncation boundaries to mapping minimum folio
    order
  mm/truncate: look up the end-edge straddler by index
  mm/truncate: fix data loss when splitting straddling large folios
    fails
  mm/truncate: clarify return value of truncate_inode_partial_folio()

 mm/internal.h |   4 +-
 mm/shmem.c    |  13 ++---
 mm/truncate.c | 128 +++++++++++++++++++++++++++++++++-----------------
 3 files changed, 91 insertions(+), 54 deletions(-)

--
2.54.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-09-24 10:31 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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:32   ` Jan Kara
2026-09-22 15:29   ` Zi Yan
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: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: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: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

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®