]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/memfd_luo: remove folio from page cache when accounting fails
authorChenghao Duan <duanchenghao@kylinos.cn>
Thu, 26 Mar 2026 08:47:26 +0000 (16:47 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Sat, 18 Apr 2026 07:10:53 +0000 (00:10 -0700)
In memfd_luo_retrieve_folios(), when shmem_inode_acct_blocks() fails
after successfully adding the folio to the page cache, the code jumps
to unlock_folio without removing the folio from the page cache.

While the folio eventually will be freed when the file is released by
memfd_luo_retrieve(), it is a good idea to directly remove a folio that
was not fully added to the file.  This avoids the possibility of
accounting mismatches in shmem or filemap core.

Fix by adding a remove_from_cache label that calls
filemap_remove_folio() before unlocking, matching the error handling
pattern in shmem_alloc_and_add_folio().

This issue was identified by AI review:
https://sashiko.dev/#/patchset/20260323110747.193569-1-duanchenghao@kylinos.cn

[pratyush@kernel.org: changelog alterations]
Link: https://lore.kernel.org/2vxzzf3lfujq.fsf@kernel.org
Link: https://lore.kernel.org/20260326084727.118437-7-duanchenghao@kylinos.cn
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Cc: Haoran Jiang <jianghaoran@kylinos.cn>
Cc: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memfd_luo.c

index eb611527dedd64008f64c1032b17f9faeaf57cdc..b02b503c750df0d353bd85c84e6468b6ab41771f 100644 (file)
@@ -461,7 +461,7 @@ static int memfd_luo_retrieve_folios(struct file *file,
                if (err) {
                        pr_err("shmem: failed to account folio index %ld(%ld pages): %d\n",
                               i, npages, err);
-                       goto unlock_folio;
+                       goto remove_from_cache;
                }
 
                nr_added_pages += npages;
@@ -474,6 +474,8 @@ static int memfd_luo_retrieve_folios(struct file *file,
 
        return 0;
 
+remove_from_cache:
+       filemap_remove_folio(folio);
 unlock_folio:
        folio_unlock(folio);
        folio_put(folio);