2022-06-06 21:19:15

by Matthew Wilcox

[permalink] [raw]
Subject: [PATCH 00/20] Convert aops->migratepage to aops->migrate_folio

I plan to submit these patches through my pagecache tree in the upcoming
merge window. I'm pretty happy that most filesystems are now using
common code for ->migrate_folio; it's not something that most filesystem
people want to care about. I'm running xfstests using xfs against it now,
but it's little more than compile tested for other filesystems.

Matthew Wilcox (Oracle) (20):
fs: Add aops->migrate_folio
mm/migrate: Convert fallback_migrate_page() to
fallback_migrate_folio()
mm/migrate: Convert writeout() to take a folio
mm/migrate: Convert buffer_migrate_page() to buffer_migrate_folio()
mm/migrate: Convert expected_page_refs() to folio_expected_refs()
btrfs: Convert btree_migratepage to migrate_folio
nfs: Convert to migrate_folio
mm/migrate: Convert migrate_page() to migrate_folio()
mm/migrate: Add filemap_migrate_folio()
btrfs: Convert btrfs_migratepage to migrate_folio
ubifs: Convert to filemap_migrate_folio()
f2fs: Convert to filemap_migrate_folio()
aio: Convert to migrate_folio
hugetlb: Convert to migrate_folio
balloon: Convert to migrate_folio
secretmem: Convert to migrate_folio
z3fold: Convert to migrate_folio
zsmalloc: Convert to migrate_folio
fs: Remove aops->migratepage()
mm/folio-compat: Remove migration compatibility functions

Documentation/filesystems/locking.rst | 5 +-
Documentation/filesystems/vfs.rst | 13 +-
Documentation/vm/page_migration.rst | 33 +--
block/fops.c | 2 +-
drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 4 +-
fs/aio.c | 36 ++--
fs/btrfs/disk-io.c | 22 +-
fs/btrfs/inode.c | 26 +--
fs/ext2/inode.c | 4 +-
fs/ext4/inode.c | 4 +-
fs/f2fs/checkpoint.c | 4 +-
fs/f2fs/data.c | 40 +---
fs/f2fs/f2fs.h | 4 -
fs/f2fs/node.c | 4 +-
fs/gfs2/aops.c | 2 +-
fs/hugetlbfs/inode.c | 19 +-
fs/iomap/buffered-io.c | 25 ---
fs/nfs/file.c | 4 +-
fs/nfs/internal.h | 6 +-
fs/nfs/write.c | 16 +-
fs/ntfs/aops.c | 6 +-
fs/ocfs2/aops.c | 2 +-
fs/ubifs/file.c | 29 +--
fs/xfs/xfs_aops.c | 2 +-
fs/zonefs/super.c | 2 +-
include/linux/buffer_head.h | 10 +
include/linux/fs.h | 18 +-
include/linux/iomap.h | 6 -
include/linux/migrate.h | 22 +-
include/linux/pagemap.h | 6 +
mm/balloon_compaction.c | 15 +-
mm/compaction.c | 5 +-
mm/folio-compat.c | 22 --
mm/ksm.c | 2 +-
mm/migrate.c | 217 ++++++++++++--------
mm/migrate_device.c | 3 +-
mm/secretmem.c | 6 +-
mm/shmem.c | 2 +-
mm/swap_state.c | 2 +-
mm/z3fold.c | 8 +-
mm/zsmalloc.c | 8 +-
41 files changed, 287 insertions(+), 379 deletions(-)

--
2.35.1


2022-06-06 21:22:23

by Matthew Wilcox

[permalink] [raw]
Subject: [PATCH 12/20] f2fs: Convert to filemap_migrate_folio()

filemap_migrate_folio() fits f2fs's needs perfectly.

Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
---
fs/f2fs/checkpoint.c | 4 +---
fs/f2fs/data.c | 40 +---------------------------------------
fs/f2fs/f2fs.h | 4 ----
fs/f2fs/node.c | 4 +---
4 files changed, 3 insertions(+), 49 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 6d8b2bf14de0..8259e0fa97e1 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -463,9 +463,7 @@ const struct address_space_operations f2fs_meta_aops = {
.dirty_folio = f2fs_dirty_meta_folio,
.invalidate_folio = f2fs_invalidate_folio,
.release_folio = f2fs_release_folio,
-#ifdef CONFIG_MIGRATION
- .migratepage = f2fs_migrate_page,
-#endif
+ .migrate_folio = filemap_migrate_folio,
};

static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 7fcbcf979737..318a3f91ad74 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3751,42 +3751,6 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
return blknr;
}

-#ifdef CONFIG_MIGRATION
-#include <linux/migrate.h>
-
-int f2fs_migrate_page(struct address_space *mapping,
- struct page *newpage, struct page *page, enum migrate_mode mode)
-{
- int rc, extra_count = 0;
-
- BUG_ON(PageWriteback(page));
-
- rc = migrate_page_move_mapping(mapping, newpage,
- page, extra_count);
- if (rc != MIGRATEPAGE_SUCCESS)
- return rc;
-
- /* guarantee to start from no stale private field */
- set_page_private(newpage, 0);
- if (PagePrivate(page)) {
- set_page_private(newpage, page_private(page));
- SetPagePrivate(newpage);
- get_page(newpage);
-
- set_page_private(page, 0);
- ClearPagePrivate(page);
- put_page(page);
- }
-
- if (mode != MIGRATE_SYNC_NO_COPY)
- migrate_page_copy(newpage, page);
- else
- migrate_page_states(newpage, page);
-
- return MIGRATEPAGE_SUCCESS;
-}
-#endif
-
#ifdef CONFIG_SWAP
static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
unsigned int blkcnt)
@@ -4018,15 +3982,13 @@ const struct address_space_operations f2fs_dblock_aops = {
.write_begin = f2fs_write_begin,
.write_end = f2fs_write_end,
.dirty_folio = f2fs_dirty_data_folio,
+ .migrate_folio = filemap_migrate_folio,
.invalidate_folio = f2fs_invalidate_folio,
.release_folio = f2fs_release_folio,
.direct_IO = noop_direct_IO,
.bmap = f2fs_bmap,
.swap_activate = f2fs_swap_activate,
.swap_deactivate = f2fs_swap_deactivate,
-#ifdef CONFIG_MIGRATION
- .migratepage = f2fs_migrate_page,
-#endif
};

void f2fs_clear_page_cache_dirty_tag(struct page *page)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d9bbecd008d2..f258a1b6faed 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3764,10 +3764,6 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
void f2fs_write_failed(struct inode *inode, loff_t to);
void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length);
bool f2fs_release_folio(struct folio *folio, gfp_t wait);
-#ifdef CONFIG_MIGRATION
-int f2fs_migrate_page(struct address_space *mapping, struct page *newpage,
- struct page *page, enum migrate_mode mode);
-#endif
bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len);
void f2fs_clear_page_cache_dirty_tag(struct page *page);
int f2fs_init_post_read_processing(void);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 836c79a20afc..ed1cbfb0345f 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2163,9 +2163,7 @@ const struct address_space_operations f2fs_node_aops = {
.dirty_folio = f2fs_dirty_node_folio,
.invalidate_folio = f2fs_invalidate_folio,
.release_folio = f2fs_release_folio,
-#ifdef CONFIG_MIGRATION
- .migratepage = f2fs_migrate_page,
-#endif
+ .migrate_folio = filemap_migrate_folio,
};

static struct free_nid *__lookup_free_nid_list(struct f2fs_nm_info *nm_i,
--
2.35.1

2022-06-06 21:32:22

by Matthew Wilcox

[permalink] [raw]
Subject: [PATCH 13/20] aio: Convert to migrate_folio

Use a folio throughout this function.

Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
---
fs/aio.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index 3c249b938632..a1911e86859c 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -400,8 +400,8 @@ static const struct file_operations aio_ring_fops = {
};

#if IS_ENABLED(CONFIG_MIGRATION)
-static int aio_migratepage(struct address_space *mapping, struct page *new,
- struct page *old, enum migrate_mode mode)
+static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
+ struct folio *src, enum migrate_mode mode)
{
struct kioctx *ctx;
unsigned long flags;
@@ -435,10 +435,10 @@ static int aio_migratepage(struct address_space *mapping, struct page *new,
goto out;
}

- idx = old->index;
+ idx = src->index;
if (idx < (pgoff_t)ctx->nr_pages) {
- /* Make sure the old page hasn't already been changed */
- if (ctx->ring_pages[idx] != old)
+ /* Make sure the old folio hasn't already been changed */
+ if (ctx->ring_pages[idx] != &src->page)
rc = -EAGAIN;
} else
rc = -EINVAL;
@@ -447,27 +447,27 @@ static int aio_migratepage(struct address_space *mapping, struct page *new,
goto out_unlock;

/* Writeback must be complete */
- BUG_ON(PageWriteback(old));
- get_page(new);
+ BUG_ON(folio_test_writeback(src));
+ folio_get(dst);

- rc = migrate_page_move_mapping(mapping, new, old, 1);
+ rc = folio_migrate_mapping(mapping, dst, src, 1);
if (rc != MIGRATEPAGE_SUCCESS) {
- put_page(new);
+ folio_put(dst);
goto out_unlock;
}

/* Take completion_lock to prevent other writes to the ring buffer
- * while the old page is copied to the new. This prevents new
+ * while the old folio is copied to the new. This prevents new
* events from being lost.
*/
spin_lock_irqsave(&ctx->completion_lock, flags);
- migrate_page_copy(new, old);
- BUG_ON(ctx->ring_pages[idx] != old);
- ctx->ring_pages[idx] = new;
+ folio_migrate_copy(dst, src);
+ BUG_ON(ctx->ring_pages[idx] != &src->page);
+ ctx->ring_pages[idx] = &dst->page;
spin_unlock_irqrestore(&ctx->completion_lock, flags);

- /* The old page is no longer accessible. */
- put_page(old);
+ /* The old folio is no longer accessible. */
+ folio_put(src);

out_unlock:
mutex_unlock(&ctx->ring_lock);
@@ -475,13 +475,13 @@ static int aio_migratepage(struct address_space *mapping, struct page *new,
spin_unlock(&mapping->private_lock);
return rc;
}
+#else
+#define aio_migrate_folio NULL
#endif

static const struct address_space_operations aio_ctx_aops = {
.dirty_folio = noop_dirty_folio,
-#if IS_ENABLED(CONFIG_MIGRATION)
- .migratepage = aio_migratepage,
-#endif
+ .migrate_folio = aio_migrate_folio,
};

static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)
--
2.35.1