@@ -1119,6 +1119,14 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
{
int rc;
+ /* Check whether src does not have extra refs before we do more work */
+ if (folio_ref_count(src) != folio_expected_refs(mapping, src))
+ return -EAGAIN;
+
+ rc = folio_mc_copy(dst, src);
+ if (rc)
+ return rc;
+
rc = migrate_huge_page_move_mapping(mapping, dst, src);
if (rc != MIGRATEPAGE_SUCCESS)
return rc;
@@ -1129,7 +1137,7 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
hugetlb_set_folio_subpool(src, NULL);
}
- folio_migrate_copy(dst, src);
+ folio_migrate_flags(dst, src);
return MIGRATEPAGE_SUCCESS;
}
@@ -79,6 +79,7 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio);
void folio_migrate_copy(struct folio *newfolio, struct folio *folio);
int folio_migrate_mapping(struct address_space *mapping,
struct folio *newfolio, struct folio *folio, int extra_count);
+int folio_expected_refs(struct address_space *mapping, struct folio *folio);
#else
@@ -375,8 +375,7 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
}
#endif
-static int folio_expected_refs(struct address_space *mapping,
- struct folio *folio)
+int folio_expected_refs(struct address_space *mapping, struct folio *folio)
{
int refs = 1;
if (!mapping)
This is similar to __migrate_folio(), use folio_mc_copy() to avoid panic when copy poisoned folio. Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> --- fs/hugetlbfs/inode.c | 10 +++++++++- include/linux/migrate.h | 1 + mm/migrate.c | 3 +-- 3 files changed, 11 insertions(+), 3 deletions(-)