diff options
-rw-r--r-- | mm/migrate.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index 13b032269242..9dd5eb846d38 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -681,16 +681,24 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, void *src_private, enum migrate_mode mode) { - int rc; + int rc, expected_count = folio_expected_refs(mapping, src); + + /* Check whether src does not have extra refs before we do more work */ + if (folio_ref_count(src) != expected_count) + return -EAGAIN; + + rc = folio_mc_copy(dst, src); + if (unlikely(rc)) + return rc; - rc = folio_migrate_mapping(mapping, dst, src, 0); + rc = __folio_migrate_mapping(mapping, dst, src, expected_count); if (rc != MIGRATEPAGE_SUCCESS) return rc; if (src_private) folio_attach_private(dst, folio_detach_private(src)); - folio_migrate_copy(dst, src); + folio_migrate_flags(dst, src); return MIGRATEPAGE_SUCCESS; } |