Re: [PATCH v2 05/47] mm/truncate: look again if a folio left the mapping

From: Zi Yan

Date: Fri Oct 30 2026 - 13:16:45 EST


On Thu Oct 29, 2026 at 4:33 PM EDT, David Hildenbrand (Arm) wrote:
> invalidate_inode_pages2_range() skips a folio which no longer belongs to
> the mapping by the time it has got the folio lock, on the assumption
> that somebody else has removed it from the page cache. But the folio may
> have been replaced, and then there is a new folio with the same data at
> that index.
>
> For most cases, like folio migration, that is impossible. However,
> collapse_file() only checks the refcount of the old folios, under the
> i_pages lock, and relies on their folio locks from there on. That works for
> users which repeat the lookup when they find folio->mapping changed.
> The following scenario is, however, possible:
>
> CPU0 pwrite(O_DIRECT) CPU1 collapse_file()
> kiocb_invalidate_pages()
> read the folio (old data), lock it
> refcount check
> the write completes copy to new_folio
> kiocb_invalidate_post_direct_write()
> find_get_entries() -> old folio
> xas_store(new_folio)
> folio->mapping = NULL
> folio_unlock(folio)
> folio_lock()
> folio->mapping != mapping
> -> continue
>
> In that scenario, the collapsed folio with the data from before the write
> stays in the page cache after the write has returned.
>
> This used to be impossible, as khugepaged only collapsed files that nobody
> had open for writing.
>
> Restart the lookup at that index, like shmem_undo_range() does. The same
> problem seems to exist in truncate_inode_pages_range() as well when
> truncate_inode_folio() fails, so handle it there as well, but slightly
> differently: simply check once more through find_get_entries().
>
> Fixes: 1b6444331beb ("mm/khugepaged: enable clean pagecache folio collapse for writable files")
> Cc: stable@xxxxxxxxxxxxxxx
> Reported-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
> Reviewed-by: Rik van Riel <riel@xxxxxxxxxxx>
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
> ---
> mm/truncate.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>

Reviewed-by: Zi Yan <ziy@xxxxxxxxxx>

--
Best Regards,
Yan, Zi