In order to support poisoned folio copy recover from migrate folio, let's use folio_mc_copy() and move it in the begin of the function of __migrate_folio(), which could simply error handling since there is no turning back if folio_migrate_mapping() return success, the downside is the folio copied even though folio_migrate_mapping() return fail, a small optimization is to check whether folio does not have extra refs before we do more work ahead in __migrate_folio(), which could help us avoid unnecessary folio copy. Signed-off-by: Kefeng Wang <wangkefeng.wang@xxxxxxxxxx> --- mm/migrate.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/migrate.c b/mm/migrate.c index 107965bbc852..99286394b5e5 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -661,6 +661,14 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst, { 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 = folio_migrate_mapping(mapping, dst, src, 0); if (rc != MIGRATEPAGE_SUCCESS) return rc; @@ -668,7 +676,7 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst, if (src_private) folio_attach_private(dst, folio_detach_private(src)); - folio_migrate_copy(dst, src); + folio_migrate_flags(dst, src); return MIGRATEPAGE_SUCCESS; } -- 2.27.0