[PATCH 10/16] mm/shmem: discard whole new large folios on fallocate rollback

From: David Hildenbrand (Arm)

Date: Mon Oct 26 2026 - 05:49:19 EST


When undoing a failed fallocate(), shmem_undo_range() must discard each
newly allocated folio. Its second scan instead passes large
folios to truncate_inode_partial_folio(), which does not necessarily
discard the entire large folio, but instead tries splitting it to
discard only the requested range.

For example, with huge=always, a failed allocation starting at offset
4 KiB can leave page 0 allocated in an otherwise empty file.

Discard the whole folio when unfalloc is set. Note that we enter this
path only for folios that are not uptodate, and can consequently be
dropped without losing any data.

Fixes: 55ac8bbe358b ("mm/shmem: fix race in shmem_undo_range w/THP")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
---
mm/shmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 938221c473f3f..c8608026e06ef 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1483,7 +1483,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
if (!unfalloc && folio_test_large(folio))
folio_mark_dirty(folio);

- if (!folio_test_large(folio)) {
+ if (unfalloc || !folio_test_large(folio)) {
truncate_inode_folio(mapping, folio);
} else if (truncate_inode_partial_folio(folio, lstart, lend)) {
/*

--
2.43.0