Use a folio throughout __buffer_migrate_folio(), add kernel-doc for
buffer_migrate_folio() and buffer_migrate_folio_norefs(), move their
declarations to buffer.h and switch all filesystems that have wired
them up.

Signed-off-by: Matthew Wilcox (Oracle) <wi...@infradead.org>
---
 block/fops.c                |  2 +-
 fs/ext2/inode.c             |  4 +-
 fs/ext4/inode.c             |  4 +-
 fs/ntfs/aops.c              |  6 +--
 fs/ocfs2/aops.c             |  2 +-
 include/linux/buffer_head.h | 10 +++++
 include/linux/fs.h          | 12 ------
 mm/migrate.c                | 76 ++++++++++++++++++++++---------------
 8 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index d6b3276a6c68..743fc46d0aad 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -417,7 +417,7 @@ const struct address_space_operations def_blk_aops = {
        .write_end      = blkdev_write_end,
        .writepages     = blkdev_writepages,
        .direct_IO      = blkdev_direct_IO,
-       .migratepage    = buffer_migrate_page_norefs,
+       .migrate_folio  = buffer_migrate_folio_norefs,
        .is_dirty_writeback = buffer_check_dirty_writeback,
 };
 
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 360ce3604a2d..84570c6265aa 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -973,7 +973,7 @@ const struct address_space_operations ext2_aops = {
        .bmap                   = ext2_bmap,
        .direct_IO              = ext2_direct_IO,
        .writepages             = ext2_writepages,
-       .migratepage            = buffer_migrate_page,
+       .migrate_folio          = buffer_migrate_folio,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page      = generic_error_remove_page,
 };
@@ -989,7 +989,7 @@ const struct address_space_operations ext2_nobh_aops = {
        .bmap                   = ext2_bmap,
        .direct_IO              = ext2_direct_IO,
        .writepages             = ext2_writepages,
-       .migratepage            = buffer_migrate_page,
+       .migrate_folio          = buffer_migrate_folio,
        .error_remove_page      = generic_error_remove_page,
 };
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1aaea53e67b5..53877ffe3c41 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3633,7 +3633,7 @@ static const struct address_space_operations ext4_aops = {
        .invalidate_folio       = ext4_invalidate_folio,
        .release_folio          = ext4_release_folio,
        .direct_IO              = noop_direct_IO,
-       .migratepage            = buffer_migrate_page,
+       .migrate_folio          = buffer_migrate_folio,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page      = generic_error_remove_page,
        .swap_activate          = ext4_iomap_swap_activate,
@@ -3668,7 +3668,7 @@ static const struct address_space_operations ext4_da_aops 
= {
        .invalidate_folio       = ext4_invalidate_folio,
        .release_folio          = ext4_release_folio,
        .direct_IO              = noop_direct_IO,
-       .migratepage            = buffer_migrate_page,
+       .migrate_folio          = buffer_migrate_folio,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page      = generic_error_remove_page,
        .swap_activate          = ext4_iomap_swap_activate,
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 9e3964ea2ea0..5f4fb6ca6f2e 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1659,7 +1659,7 @@ const struct address_space_operations ntfs_normal_aops = {
        .dirty_folio    = block_dirty_folio,
 #endif /* NTFS_RW */
        .bmap           = ntfs_bmap,
-       .migratepage    = buffer_migrate_page,
+       .migrate_folio  = buffer_migrate_folio,
        .is_partially_uptodate = block_is_partially_uptodate,
        .error_remove_page = generic_error_remove_page,
 };
@@ -1673,7 +1673,7 @@ const struct address_space_operations 
ntfs_compressed_aops = {
        .writepage      = ntfs_writepage,
        .dirty_folio    = block_dirty_folio,
 #endif /* NTFS_RW */
-       .migratepage    = buffer_migrate_page,
+       .migrate_folio  = buffer_migrate_folio,
        .is_partially_uptodate = block_is_partially_uptodate,
        .error_remove_page = generic_error_remove_page,
 };
@@ -1688,7 +1688,7 @@ const struct address_space_operations ntfs_mst_aops = {
        .writepage      = ntfs_writepage,       /* Write dirty page to disk. */
        .dirty_folio    = filemap_dirty_folio,
 #endif /* NTFS_RW */
-       .migratepage    = buffer_migrate_page,
+       .migrate_folio  = buffer_migrate_folio,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page = generic_error_remove_page,
 };
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 767df51f8657..1d489003f99d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -2462,7 +2462,7 @@ const struct address_space_operations ocfs2_aops = {
        .direct_IO              = ocfs2_direct_IO,
        .invalidate_folio       = block_invalidate_folio,
        .release_folio          = ocfs2_release_folio,
-       .migratepage            = buffer_migrate_page,
+       .migrate_folio          = buffer_migrate_folio,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page      = generic_error_remove_page,
 };
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index c9d1463bb20f..b0366c89d6a4 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -267,6 +267,16 @@ int nobh_truncate_page(struct address_space *, loff_t, 
get_block_t *);
 int nobh_writepage(struct page *page, get_block_t *get_block,
                         struct writeback_control *wbc);
 
+#ifdef CONFIG_MIGRATION
+extern int buffer_migrate_folio(struct address_space *,
+               struct folio *dst, struct folio *src, enum migrate_mode);
+extern int buffer_migrate_folio_norefs(struct address_space *,
+               struct folio *dst, struct folio *src, enum migrate_mode);
+#else
+#define buffer_migrate_folio NULL
+#define buffer_migrate_folio_norefs NULL
+#endif
+
 void buffer_init(void);
 
 /*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7b380fa66983..5737c92ed286 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3217,18 +3217,6 @@ extern int generic_check_addressable(unsigned, u64);
 
 extern void generic_set_encrypted_ci_d_ops(struct dentry *dentry);
 
-#ifdef CONFIG_MIGRATION
-extern int buffer_migrate_page(struct address_space *,
-                               struct page *, struct page *,
-                               enum migrate_mode);
-extern int buffer_migrate_page_norefs(struct address_space *,
-                               struct page *, struct page *,
-                               enum migrate_mode);
-#else
-#define buffer_migrate_page NULL
-#define buffer_migrate_page_norefs NULL
-#endif
-
 int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
                unsigned int ia_valid);
 int setattr_prepare(struct user_namespace *, struct dentry *, struct iattr *);
diff --git a/mm/migrate.c b/mm/migrate.c
index f19246c12fe9..77b8c662c9ca 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -657,23 +657,23 @@ static bool buffer_migrate_lock_buffers(struct 
buffer_head *head,
        return true;
 }
 
-static int __buffer_migrate_page(struct address_space *mapping,
-               struct page *newpage, struct page *page, enum migrate_mode mode,
+static int __buffer_migrate_folio(struct address_space *mapping,
+               struct folio *dst, struct folio *src, enum migrate_mode mode,
                bool check_refs)
 {
        struct buffer_head *bh, *head;
        int rc;
        int expected_count;
 
-       if (!page_has_buffers(page))
-               return migrate_page(mapping, newpage, page, mode);
+       head = folio_buffers(src);
+       if (!head)
+               return migrate_page(mapping, &dst->page, &src->page, mode);
 
        /* Check whether page does not have extra refs before we do more work */
-       expected_count = expected_page_refs(mapping, page);
-       if (page_count(page) != expected_count)
+       expected_count = expected_page_refs(mapping, &src->page);
+       if (folio_ref_count(src) != expected_count)
                return -EAGAIN;
 
-       head = page_buffers(page);
        if (!buffer_migrate_lock_buffers(head, mode))
                return -EAGAIN;
 
@@ -704,23 +704,22 @@ static int __buffer_migrate_page(struct address_space 
*mapping,
                }
        }
 
-       rc = migrate_page_move_mapping(mapping, newpage, page, 0);
+       rc = folio_migrate_mapping(mapping, dst, src, 0);
        if (rc != MIGRATEPAGE_SUCCESS)
                goto unlock_buffers;
 
-       attach_page_private(newpage, detach_page_private(page));
+       folio_attach_private(dst, folio_detach_private(src));
 
        bh = head;
        do {
-               set_bh_page(bh, newpage, bh_offset(bh));
+               set_bh_page(bh, &dst->page, bh_offset(bh));
                bh = bh->b_this_page;
-
        } while (bh != head);
 
        if (mode != MIGRATE_SYNC_NO_COPY)
-               migrate_page_copy(newpage, page);
+               folio_migrate_copy(dst, src);
        else
-               migrate_page_states(newpage, page);
+               folio_migrate_flags(dst, src);
 
        rc = MIGRATEPAGE_SUCCESS;
 unlock_buffers:
@@ -730,34 +729,51 @@ static int __buffer_migrate_page(struct address_space 
*mapping,
        do {
                unlock_buffer(bh);
                bh = bh->b_this_page;
-
        } while (bh != head);
 
        return rc;
 }
 
-/*
- * Migration function for pages with buffers. This function can only be used
- * if the underlying filesystem guarantees that no other references to "page"
- * exist. For example attached buffer heads are accessed only under page lock.
+/**
+ * buffer_migrate_folio() - Migration function for folios with buffers.
+ * @mapping: The address space containing @src.
+ * @dst: The folio to migrate to.
+ * @src: The folio to migrate from.
+ * @mode: How to migrate the folio.
+ *
+ * This function can only be used if the underlying filesystem guarantees
+ * that no other references to @src exist. For example attached buffer
+ * heads are accessed only under the folio lock.  If your filesystem cannot
+ * provide this guarantee, buffer_migrate_folio_noref() may be more
+ * appropriate.
+ *
+ * Return: 0 on success or a negative errno on failure.
  */
-int buffer_migrate_page(struct address_space *mapping,
-               struct page *newpage, struct page *page, enum migrate_mode mode)
+int buffer_migrate_folio(struct address_space *mapping,
+               struct folio *dst, struct folio *src, enum migrate_mode mode)
 {
-       return __buffer_migrate_page(mapping, newpage, page, mode, false);
+       return __buffer_migrate_folio(mapping, dst, src, mode, false);
 }
-EXPORT_SYMBOL(buffer_migrate_page);
+EXPORT_SYMBOL(buffer_migrate_folio);
 
-/*
- * Same as above except that this variant is more careful and checks that there
- * are also no buffer head references. This function is the right one for
- * mappings where buffer heads are directly looked up and referenced (such as
- * block device mappings).
+/**
+ * buffer_migrate_folio_noref() - Migration function for folios with buffers.
+ * @mapping: The address space containing @src.
+ * @dst: The folio to migrate to.
+ * @src: The folio to migrate from.
+ * @mode: How to migrate the folio.
+ *
+ * Like buffer_migrate_folio() except that this variant is more careful
+ * and checks that there are also no buffer head references. This function
+ * is the right one for mappings where buffer heads are directly looked
+ * up and referenced (such as block device mappings).
+ *
+ * Return: 0 on success or a negative errno on failure.
  */
-int buffer_migrate_page_norefs(struct address_space *mapping,
-               struct page *newpage, struct page *page, enum migrate_mode mode)
+int buffer_migrate_folio_norefs(struct address_space *mapping,
+               struct folio *dst, struct folio *src, enum migrate_mode mode)
 {
-       return __buffer_migrate_page(mapping, newpage, page, mode, true);
+       return __buffer_migrate_folio(mapping, dst, src, mode, true);
 }
 #endif
 
-- 
2.35.1

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to