diff mbox series

[1/2] fs: Convert writepage_t callback to pass a folio

Message ID 20230126201255.1681189-2-willy@infradead.org (mailing list archive)
State New
Headers show
Series Convert writepage_t to use a folio | expand

Commit Message

Matthew Wilcox Jan. 26, 2023, 8:12 p.m. UTC
We always write back an entire folio, but that's currently passed as
the head page.  Convert all filesystems that use write_cache_pages()
to expect a folio instead of a page.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 fs/cifs/file.c            |  8 ++++----
 fs/ext4/inode.c           |  4 ++--
 fs/ext4/super.c           |  6 +++---
 fs/fuse/file.c            | 18 +++++++++---------
 fs/iomap/buffered-io.c    |  5 ++---
 fs/mpage.c                |  3 ++-
 fs/nfs/write.c            |  7 ++++---
 fs/ntfs3/inode.c          |  6 +++---
 fs/orangefs/inode.c       | 23 +++++++++++------------
 include/linux/writeback.h |  2 +-
 mm/page-writeback.c       |  6 +++---
 11 files changed, 44 insertions(+), 44 deletions(-)

Comments

kernel test robot Jan. 28, 2023, 5:13 p.m. UTC | #1
Hi Matthew,

I love your patch! Yet something to improve:

[auto build test ERROR on next-20230125]
[cannot apply to tytso-ext4/dev akpm-mm/mm-everything cifs/for-next mszeredi-fuse/for-next xfs-linux/for-next trondmy-nfs/linux-next hubcap/for-next linus/master v6.2-rc5 v6.2-rc4 v6.2-rc3 v6.2-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/fs-Convert-writepage_t-callback-to-pass-a-folio/20230128-112951
patch link:    https://lore.kernel.org/r/20230126201255.1681189-2-willy%40infradead.org
patch subject: [PATCH 1/2] fs: Convert writepage_t callback to pass a folio
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20230129/202301290130.frg9YGk5-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/19e834de445f5d3a390fff94320e71e8077ce632
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Matthew-Wilcox-Oracle/fs-Convert-writepage_t-callback-to-pass-a-folio/20230128-112951
        git checkout 19e834de445f5d3a390fff94320e71e8077ce632
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash fs/gfs2/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   fs/gfs2/log.c: In function 'gfs2_ail1_start_one':
>> fs/gfs2/log.c:143:55: error: passing argument 3 of 'write_cache_pages' from incompatible pointer type [-Werror=incompatible-pointer-types]
     143 |                 ret = write_cache_pages(mapping, wbc, __gfs2_writepage, mapping);
         |                                                       ^~~~~~~~~~~~~~~~
         |                                                       |
         |                                                       int (*)(struct page *, struct writeback_control *, void *)
   In file included from fs/gfs2/log.c:20:
   include/linux/writeback.h:375:66: note: expected 'writepage_t' {aka 'int (*)(struct folio *, struct writeback_control *, void *)'} but argument is of type 'int (*)(struct page *, struct writeback_control *, void *)'
     375 |                       struct writeback_control *wbc, writepage_t writepage,
         |                                                      ~~~~~~~~~~~~^~~~~~~~~
   cc1: some warnings being treated as errors


vim +/write_cache_pages +143 fs/gfs2/log.c

95ecbd0f162fc0 Andreas Gruenbacher     2023-01-19   91  
ddacfaf76dd620 Steven Whitehouse       2006-10-03   92  /**
c551f66c5dfefd Lee Jones               2021-03-30   93   * gfs2_ail1_start_one - Start I/O on a transaction
c551f66c5dfefd Lee Jones               2021-03-30   94   * @sdp: The superblock
4667a0ec328678 Steven Whitehouse       2011-04-18   95   * @wbc: The writeback control structure
c551f66c5dfefd Lee Jones               2021-03-30   96   * @tr: The transaction to start I/O on
c551f66c5dfefd Lee Jones               2021-03-30   97   * @plug: The block plug currently active
ddacfaf76dd620 Steven Whitehouse       2006-10-03   98   */
ddacfaf76dd620 Steven Whitehouse       2006-10-03   99  
4f1de018215fb5 Steven Whitehouse       2011-04-26  100  static int gfs2_ail1_start_one(struct gfs2_sbd *sdp,
4667a0ec328678 Steven Whitehouse       2011-04-18  101  			       struct writeback_control *wbc,
17d77684088510 Bob Peterson            2021-02-18  102  			       struct gfs2_trans *tr, struct blk_plug *plug)
d6a079e82efd5f Dave Chinner            2011-03-11  103  __releases(&sdp->sd_ail_lock)
d6a079e82efd5f Dave Chinner            2011-03-11  104  __acquires(&sdp->sd_ail_lock)
ddacfaf76dd620 Steven Whitehouse       2006-10-03  105  {
5ac048bb7ea6e8 Steven Whitehouse       2011-03-30  106  	struct gfs2_glock *gl = NULL;
4667a0ec328678 Steven Whitehouse       2011-04-18  107  	struct address_space *mapping;
ddacfaf76dd620 Steven Whitehouse       2006-10-03  108  	struct gfs2_bufdata *bd, *s;
ddacfaf76dd620 Steven Whitehouse       2006-10-03  109  	struct buffer_head *bh;
b1676cbb11153b Bob Peterson            2019-11-13  110  	int ret = 0;
ddacfaf76dd620 Steven Whitehouse       2006-10-03  111  
16ca9412d80181 Benjamin Marzinski      2013-04-05  112  	list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) {
ddacfaf76dd620 Steven Whitehouse       2006-10-03  113  		bh = bd->bd_bh;
ddacfaf76dd620 Steven Whitehouse       2006-10-03  114  
16ca9412d80181 Benjamin Marzinski      2013-04-05  115  		gfs2_assert(sdp, bd->bd_tr == tr);
ddacfaf76dd620 Steven Whitehouse       2006-10-03  116  
ddacfaf76dd620 Steven Whitehouse       2006-10-03  117  		if (!buffer_busy(bh)) {
30fe70a85a909a Bob Peterson            2019-11-13  118  			if (buffer_uptodate(bh)) {
30fe70a85a909a Bob Peterson            2019-11-13  119  				list_move(&bd->bd_ail_st_list,
30fe70a85a909a Bob Peterson            2019-11-13  120  					  &tr->tr_ail2_list);
30fe70a85a909a Bob Peterson            2019-11-13  121  				continue;
30fe70a85a909a Bob Peterson            2019-11-13  122  			}
036330c914365f Bob Peterson            2019-04-10  123  			if (!cmpxchg(&sdp->sd_log_error, 0, -EIO)) {
ddacfaf76dd620 Steven Whitehouse       2006-10-03  124  				gfs2_io_error_bh(sdp, bh);
69511080bd6efd Bob Peterson            2019-02-12  125  				gfs2_withdraw_delayed(sdp);
9e1a9ecd13b9bb Andreas Gruenbacher     2018-06-07  126  			}
ddacfaf76dd620 Steven Whitehouse       2006-10-03  127  		}
ddacfaf76dd620 Steven Whitehouse       2006-10-03  128  
30fe70a85a909a Bob Peterson            2019-11-13  129  		if (gfs2_withdrawn(sdp)) {
30fe70a85a909a Bob Peterson            2019-11-13  130  			gfs2_remove_from_ail(bd);
30fe70a85a909a Bob Peterson            2019-11-13  131  			continue;
30fe70a85a909a Bob Peterson            2019-11-13  132  		}
ddacfaf76dd620 Steven Whitehouse       2006-10-03  133  		if (!buffer_dirty(bh))
ddacfaf76dd620 Steven Whitehouse       2006-10-03  134  			continue;
5ac048bb7ea6e8 Steven Whitehouse       2011-03-30  135  		if (gl == bd->bd_gl)
5ac048bb7ea6e8 Steven Whitehouse       2011-03-30  136  			continue;
5ac048bb7ea6e8 Steven Whitehouse       2011-03-30  137  		gl = bd->bd_gl;
16ca9412d80181 Benjamin Marzinski      2013-04-05  138  		list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list);
11551cf15ecc17 Matthew Wilcox (Oracle  2022-12-15  139) 		mapping = bh->b_folio->mapping;
4f1de018215fb5 Steven Whitehouse       2011-04-26  140  		if (!mapping)
4f1de018215fb5 Steven Whitehouse       2011-04-26  141  			continue;
d6a079e82efd5f Dave Chinner            2011-03-11  142  		spin_unlock(&sdp->sd_ail_lock);
95ecbd0f162fc0 Andreas Gruenbacher     2023-01-19 @143  		ret = write_cache_pages(mapping, wbc, __gfs2_writepage, mapping);
17d77684088510 Bob Peterson            2021-02-18  144  		if (need_resched()) {
17d77684088510 Bob Peterson            2021-02-18  145  			blk_finish_plug(plug);
17d77684088510 Bob Peterson            2021-02-18  146  			cond_resched();
17d77684088510 Bob Peterson            2021-02-18  147  			blk_start_plug(plug);
17d77684088510 Bob Peterson            2021-02-18  148  		}
d6a079e82efd5f Dave Chinner            2011-03-11  149  		spin_lock(&sdp->sd_ail_lock);
4e79e3f08e576a Bob Peterson            2020-11-12  150  		if (ret == -ENODATA) /* if a jdata write into a new hole */
4e79e3f08e576a Bob Peterson            2020-11-12  151  			ret = 0; /* ignore it */
b1676cbb11153b Bob Peterson            2019-11-13  152  		if (ret || wbc->nr_to_write <= 0)
4667a0ec328678 Steven Whitehouse       2011-04-18  153  			break;
b1676cbb11153b Bob Peterson            2019-11-13  154  		return -EBUSY;
4667a0ec328678 Steven Whitehouse       2011-04-18  155  	}
4f1de018215fb5 Steven Whitehouse       2011-04-26  156  
b1676cbb11153b Bob Peterson            2019-11-13  157  	return ret;
4667a0ec328678 Steven Whitehouse       2011-04-18  158  }
ddacfaf76dd620 Steven Whitehouse       2006-10-03  159
Andrew Morton Jan. 29, 2023, 9:33 p.m. UTC | #2
On Sun, 29 Jan 2023 01:13:56 +0800 kernel test robot <lkp@intel.com> wrote:

> Hi Matthew,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on next-20230125]
> [cannot apply to tytso-ext4/dev akpm-mm/mm-everything cifs/for-next mszeredi-fuse/for-next xfs-linux/for-next trondmy-nfs/linux-next hubcap/for-next linus/master v6.2-rc5 v6.2-rc4 v6.2-rc3 v6.2-rc5]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/fs-Convert-writepage_t-callback-to-pass-a-folio/20230128-112951
> patch link:    https://lore.kernel.org/r/20230126201255.1681189-2-willy%40infradead.org
> patch subject: [PATCH 1/2] fs: Convert writepage_t callback to pass a folio
> config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20230129/202301290130.frg9YGk5-lkp@intel.com/config)
> compiler: s390-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/19e834de445f5d3a390fff94320e71e8077ce632
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Matthew-Wilcox-Oracle/fs-Convert-writepage_t-callback-to-pass-a-folio/20230128-112951
>         git checkout 19e834de445f5d3a390fff94320e71e8077ce632
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash fs/gfs2/
> 
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>    fs/gfs2/log.c: In function 'gfs2_ail1_start_one':
> >> fs/gfs2/log.c:143:55: error: passing argument 3 of 'write_cache_pages' from incompatible pointer type [-Werror=incompatible-pointer-types]
>      143 |                 ret = write_cache_pages(mapping, wbc, __gfs2_writepage, mapping);
>          |                                                       ^~~~~~~~~~~~~~~~

Thanks.  This is due to a conflict with a recent upstream merge from
the GFS tree.  Stephen addressed this in linux-next:

https://lkml.kernel.org/r/20230127173638.1efbe423@canb.auug.org.au

a) I could rebase mm.git onto -rc5 or later.

b) Or I could disable Matthew's patches until late merge window,
   after I resync with mainline for stragglers such as this.

c) Or I could do nothing - things will get sorted out once Matthew's
   commits hit mainline during the regular merge.

Perhaps a)?  People don't want to have to deal with conflicts when
merging current mm.git onto current mainline.
diff mbox series

Patch

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index bc4d9951c412..5568a5f4bc5a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2676,14 +2676,14 @@  wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
 static int
 cifs_writepage_locked(struct page *page, struct writeback_control *wbc);
 
-static int cifs_write_one_page(struct page *page, struct writeback_control *wbc,
-		void *data)
+static int cifs_write_one_page(struct folio *folio,
+		struct writeback_control *wbc, void *data)
 {
 	struct address_space *mapping = data;
 	int ret;
 
-	ret = cifs_writepage_locked(page, wbc);
-	unlock_page(page);
+	ret = cifs_writepage_locked(&folio->page, wbc);
+	folio_unlock(folio);
 	mapping_set_error(mapping, ret);
 	return ret;
 }
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 977b65580ad5..b8b3e2e0d9fd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2710,10 +2710,10 @@  static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
 	return err;
 }
 
-static int ext4_writepage_cb(struct page *page, struct writeback_control *wbc,
+static int ext4_writepage_cb(struct folio *folio, struct writeback_control *wbc,
 			     void *data)
 {
-	return ext4_writepage(page, wbc);
+	return ext4_writepage(&folio->page, wbc);
 }
 
 static int ext4_do_writepages(struct mpage_da_data *mpd)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b31db521d6bf..b8aaf55dff34 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -482,7 +482,7 @@  static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
  *
  * However, we may have to redirty a page (see below.)
  */
-static int ext4_journalled_writepage_callback(struct page *page,
+static int ext4_journalled_writepage_callback(struct folio *folio,
 					      struct writeback_control *wbc,
 					      void *data)
 {
@@ -490,7 +490,7 @@  static int ext4_journalled_writepage_callback(struct page *page,
 	struct buffer_head *bh, *head;
 	struct journal_head *jh;
 
-	bh = head = page_buffers(page);
+	bh = head = folio_buffers(folio);
 	do {
 		/*
 		 * We have to redirty a page in these cases:
@@ -509,7 +509,7 @@  static int ext4_journalled_writepage_callback(struct page *page,
 		if (buffer_dirty(bh) ||
 		    (jh && (jh->b_transaction != transaction ||
 			    jh->b_next_transaction))) {
-			redirty_page_for_writepage(wbc, page);
+			folio_redirty_for_writepage(wbc, folio);
 			goto out;
 		}
 	} while ((bh = bh->b_this_page) != head);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 82710d103556..ff0b3ef774d4 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2186,7 +2186,7 @@  static bool fuse_writepage_need_send(struct fuse_conn *fc, struct page *page,
 	return false;
 }
 
-static int fuse_writepages_fill(struct page *page,
+static int fuse_writepages_fill(struct folio *folio,
 		struct writeback_control *wbc, void *_data)
 {
 	struct fuse_fill_wb_data *data = _data;
@@ -2205,7 +2205,7 @@  static int fuse_writepages_fill(struct page *page,
 			goto out_unlock;
 	}
 
-	if (wpa && fuse_writepage_need_send(fc, page, ap, data)) {
+	if (wpa && fuse_writepage_need_send(fc, &folio->page, ap, data)) {
 		fuse_writepages_send(data);
 		data->wpa = NULL;
 	}
@@ -2240,7 +2240,7 @@  static int fuse_writepages_fill(struct page *page,
 		data->max_pages = 1;
 
 		ap = &wpa->ia.ap;
-		fuse_write_args_fill(&wpa->ia, data->ff, page_offset(page), 0);
+		fuse_write_args_fill(&wpa->ia, data->ff, folio_pos(folio), 0);
 		wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
 		wpa->next = NULL;
 		ap->args.in_pages = true;
@@ -2248,13 +2248,13 @@  static int fuse_writepages_fill(struct page *page,
 		ap->num_pages = 0;
 		wpa->inode = inode;
 	}
-	set_page_writeback(page);
+	folio_start_writeback(folio);
 
-	copy_highpage(tmp_page, page);
+	copy_highpage(tmp_page, &folio->page);
 	ap->pages[ap->num_pages] = tmp_page;
 	ap->descs[ap->num_pages].offset = 0;
 	ap->descs[ap->num_pages].length = PAGE_SIZE;
-	data->orig_pages[ap->num_pages] = page;
+	data->orig_pages[ap->num_pages] = &folio->page;
 
 	inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
 	inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);
@@ -2268,13 +2268,13 @@  static int fuse_writepages_fill(struct page *page,
 		spin_lock(&fi->lock);
 		ap->num_pages++;
 		spin_unlock(&fi->lock);
-	} else if (fuse_writepage_add(wpa, page)) {
+	} else if (fuse_writepage_add(wpa, &folio->page)) {
 		data->wpa = wpa;
 	} else {
-		end_page_writeback(page);
+		folio_end_writeback(folio);
 	}
 out_unlock:
-	unlock_page(page);
+	folio_unlock(folio);
 
 	return err;
 }
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index d3c300563eb8..6f4c97a6d7e9 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -1714,10 +1714,9 @@  iomap_writepage_map(struct iomap_writepage_ctx *wpc,
  * For unwritten space on the page, we need to start the conversion to
  * regular allocated space.
  */
-static int
-iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data)
+static int iomap_do_writepage(struct folio *folio,
+		struct writeback_control *wbc, void *data)
 {
-	struct folio *folio = page_folio(page);
 	struct iomap_writepage_ctx *wpc = data;
 	struct inode *inode = folio->mapping->host;
 	u64 end_pos, isize;
diff --git a/fs/mpage.c b/fs/mpage.c
index b8e7975159bc..840f57ed2542 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -445,9 +445,10 @@  void clean_page_buffers(struct page *page)
 	clean_buffers(page, ~0U);
 }
 
-static int __mpage_writepage(struct page *page, struct writeback_control *wbc,
+static int __mpage_writepage(struct folio *folio, struct writeback_control *wbc,
 		      void *data)
 {
+	struct page *page = &folio->page;
 	struct mpage_data *mpd = data;
 	struct bio *bio = mpd->bio;
 	struct address_space *mapping = page->mapping;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 1a80d548253a..ba3799097d1a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -690,13 +690,14 @@  int nfs_writepage(struct page *page, struct writeback_control *wbc)
 	return ret;
 }
 
-static int nfs_writepages_callback(struct page *page, struct writeback_control *wbc, void *data)
+static int nfs_writepages_callback(struct folio *folio,
+		struct writeback_control *wbc, void *data)
 {
 	int ret;
 
-	ret = nfs_do_writepage(page, wbc, data);
+	ret = nfs_do_writepage(&folio->page, wbc, data);
 	if (ret != AOP_WRITEPAGE_ACTIVATE)
-		unlock_page(page);
+		folio_unlock(folio);
 	return ret;
 }
 
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index bc4c9e35a6fc..3d2e4c1270e4 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -844,7 +844,7 @@  int ntfs_set_size(struct inode *inode, u64 new_size)
 	return err;
 }
 
-static int ntfs_resident_writepage(struct page *page,
+static int ntfs_resident_writepage(struct folio *folio,
 		struct writeback_control *wbc, void *data)
 {
 	struct address_space *mapping = data;
@@ -852,11 +852,11 @@  static int ntfs_resident_writepage(struct page *page,
 	int ret;
 
 	ni_lock(ni);
-	ret = attr_data_write_resident(ni, page);
+	ret = attr_data_write_resident(ni, &folio->page);
 	ni_unlock(ni);
 
 	if (ret != E_NTFS_NONRESIDENT)
-		unlock_page(page);
+		folio_unlock(folio);
 	mapping_set_error(mapping, ret);
 	return ret;
 }
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 11e21a0e65ce..c4c135f96aab 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -154,21 +154,20 @@  static int orangefs_writepages_work(struct orangefs_writepages *ow,
 	return ret;
 }
 
-static int orangefs_writepages_callback(struct page *page,
-    struct writeback_control *wbc, void *data)
+static int orangefs_writepages_callback(struct folio *folio,
+		struct writeback_control *wbc, void *data)
 {
 	struct orangefs_writepages *ow = data;
-	struct orangefs_write_range *wr;
+	struct orangefs_write_range *wr = folio->private;
 	int ret;
 
-	if (!PagePrivate(page)) {
-		unlock_page(page);
+	if (!wr) {
+		folio_unlock(folio);
 		/* It's not private so there's nothing to write, right? */
 		printk("writepages_callback not private!\n");
 		BUG();
 		return 0;
 	}
-	wr = (struct orangefs_write_range *)page_private(page);
 
 	ret = -1;
 	if (ow->npages == 0) {
@@ -176,7 +175,7 @@  static int orangefs_writepages_callback(struct page *page,
 		ow->len = wr->len;
 		ow->uid = wr->uid;
 		ow->gid = wr->gid;
-		ow->pages[ow->npages++] = page;
+		ow->pages[ow->npages++] = &folio->page;
 		ret = 0;
 		goto done;
 	}
@@ -188,7 +187,7 @@  static int orangefs_writepages_callback(struct page *page,
 	}
 	if (ow->off + ow->len == wr->pos) {
 		ow->len += wr->len;
-		ow->pages[ow->npages++] = page;
+		ow->pages[ow->npages++] = &folio->page;
 		ret = 0;
 		goto done;
 	}
@@ -198,10 +197,10 @@  static int orangefs_writepages_callback(struct page *page,
 			orangefs_writepages_work(ow, wbc);
 			ow->npages = 0;
 		}
-		ret = orangefs_writepage_locked(page, wbc);
-		mapping_set_error(page->mapping, ret);
-		unlock_page(page);
-		end_page_writeback(page);
+		ret = orangefs_writepage_locked(&folio->page, wbc);
+		mapping_set_error(folio->mapping, ret);
+		folio_unlock(folio);
+		folio_end_writeback(folio);
 	} else {
 		if (ow->npages == ow->maxpages) {
 			orangefs_writepages_work(ow, wbc);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 3f1491b07474..46020373e155 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -366,7 +366,7 @@  int balance_dirty_pages_ratelimited_flags(struct address_space *mapping,
 
 bool wb_over_bg_thresh(struct bdi_writeback *wb);
 
-typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc,
+typedef int (*writepage_t)(struct folio *folio, struct writeback_control *wbc,
 				void *data);
 
 void tag_pages_for_writeback(struct address_space *mapping,
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 92b90d2ab513..516b1aa247e8 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2470,7 +2470,7 @@  int write_cache_pages(struct address_space *mapping,
 				goto continue_unlock;
 
 			trace_wbc_writepage(wbc, inode_to_bdi(mapping->host));
-			error = writepage(&folio->page, wbc, data);
+			error = writepage(folio, wbc, data);
 			if (unlikely(error)) {
 				/*
 				 * Handle errors according to the type of
@@ -2528,11 +2528,11 @@  int write_cache_pages(struct address_space *mapping,
 }
 EXPORT_SYMBOL(write_cache_pages);
 
-static int writepage_cb(struct page *page, struct writeback_control *wbc,
+static int writepage_cb(struct folio *folio, struct writeback_control *wbc,
 		void *data)
 {
 	struct address_space *mapping = data;
-	int ret = mapping->a_ops->writepage(page, wbc);
+	int ret = mapping->a_ops->writepage(&folio->page, wbc);
 	mapping_set_error(mapping, ret);
 	return ret;
 }