Commit 0c493b5c authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFS: Convert buffered writes to use folios



Mostly mechanical conversion of struct page and functions into struct
folio equivalents.
The lack of support for folios in write_cache_pages(), means we still
only support order 0 folio allocations. However the rest of the
writeback code should now be ready for order n > 0.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 5241060e
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
	int ret;
	pgoff_t index = pos >> PAGE_SHIFT;
	struct page *page;
	struct folio *folio;
	int once_thru = 0;

	dfprintk(PAGECACHE, "NFS: write_begin(%pD2(%lu), %u@%lld)\n",
@@ -329,15 +330,16 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
	if (!page)
		return -ENOMEM;
	*pagep = page;
	folio = page_folio(page);

	ret = nfs_flush_incompatible(file, page);
	ret = nfs_flush_incompatible(file, folio);
	if (ret) {
		unlock_page(page);
		put_page(page);
	} else if (!once_thru &&
		   nfs_want_read_modify_write(file, page, pos, len)) {
		once_thru = 1;
		ret = nfs_read_folio(file, page_folio(page));
		ret = nfs_read_folio(file, folio);
		put_page(page);
		if (!ret)
			goto start;
@@ -351,6 +353,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
{
	unsigned offset = pos & (PAGE_SIZE - 1);
	struct nfs_open_context *ctx = nfs_file_open_context(file);
	struct folio *folio = page_folio(page);
	int status;

	dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n",
@@ -376,7 +379,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
			zero_user_segment(page, pglen, PAGE_SIZE);
	}

	status = nfs_updatepage(file, page, offset, copied);
	status = nfs_update_folio(file, folio, offset, copied);

	unlock_page(page);
	put_page(page);
@@ -552,6 +555,7 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
	unsigned pagelen;
	vm_fault_t ret = VM_FAULT_NOPAGE;
	struct address_space *mapping;
	struct folio *folio = page_folio(page);

	dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%pD2(%lu), offset %lld)\n",
		filp, filp->f_mapping->host->i_ino,
@@ -582,8 +586,8 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
		goto out_unlock;

	ret = VM_FAULT_LOCKED;
	if (nfs_flush_incompatible(filp, page) == 0 &&
	    nfs_updatepage(filp, page, 0, pagelen) == 0)
	if (nfs_flush_incompatible(filp, folio) == 0 &&
	    nfs_update_folio(filp, folio, 0, pagelen) == 0)
		goto out;

	ret = VM_FAULT_SIGBUS;
+7 −6
Original line number Diff line number Diff line
@@ -760,17 +760,18 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
 * Record the page as unstable (an extra writeback period) and mark its
 * inode as dirty.
 */
static inline
void nfs_mark_page_unstable(struct page *page, struct nfs_commit_info *cinfo)
static inline void nfs_folio_mark_unstable(struct folio *folio,
					   struct nfs_commit_info *cinfo)
{
	if (!cinfo->dreq) {
		struct inode *inode = page_file_mapping(page)->host;
	if (folio && !cinfo->dreq) {
		struct inode *inode = folio_file_mapping(folio)->host;
		long nr = folio_nr_pages(folio);

		/* This page is really still in write-back - just that the
		 * writeback is happening on the server now.
		 */
		inc_node_page_state(page, NR_WRITEBACK);
		inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
		node_stat_mod_folio(folio, NR_WRITEBACK, nr);
		wb_stat_mod(&inode_to_bdi(inode)->wb, WB_WRITEBACK, nr);
		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
	}
}
+5 −5
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ struct pnfs_commit_ops {
	void (*recover_commit_reqs) (struct list_head *list,
				     struct nfs_commit_info *cinfo);
	struct nfs_page * (*search_commit_reqs)(struct nfs_commit_info *cinfo,
						struct page *page);
						struct folio *folio);
};

struct pnfs_layout_hdr {
@@ -395,7 +395,7 @@ void pnfs_generic_rw_release(void *data);
void pnfs_generic_recover_commit_reqs(struct list_head *dst,
				      struct nfs_commit_info *cinfo);
struct nfs_page *pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo,
						 struct page *page);
						 struct folio *folio);
int pnfs_generic_commit_pagelist(struct inode *inode,
				 struct list_head *mds_pages,
				 int how,
@@ -557,13 +557,13 @@ pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)

static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
			struct page *page)
			struct folio *folio)
{
	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;

	if (!fl_cinfo->ops || !fl_cinfo->ops->search_commit_reqs)
		return NULL;
	return fl_cinfo->ops->search_commit_reqs(cinfo, page);
	return fl_cinfo->ops->search_commit_reqs(cinfo, folio);
}

/* Should the pNFS client commit and return the layout upon a setattr */
@@ -864,7 +864,7 @@ pnfs_recover_commit_reqs(struct list_head *head, struct nfs_commit_info *cinfo)

static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
			struct page *page)
			struct folio *folio)
{
	return NULL;
}
+9 −9
Original line number Diff line number Diff line
@@ -353,7 +353,7 @@ EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);

static struct nfs_page *
pnfs_bucket_search_commit_reqs(struct pnfs_commit_bucket *buckets,
		unsigned int nbuckets, struct page *page)
			       unsigned int nbuckets, struct folio *folio)
{
	struct nfs_page *req;
	struct pnfs_commit_bucket *b;
@@ -363,11 +363,11 @@ pnfs_bucket_search_commit_reqs(struct pnfs_commit_bucket *buckets,
	 * request is found */
	for (i = 0, b = buckets; i < nbuckets; i++, b++) {
		list_for_each_entry(req, &b->written, wb_list) {
			if (req->wb_page == page)
			if (nfs_page_to_folio(req) == folio)
				return req->wb_head;
		}
		list_for_each_entry(req, &b->committing, wb_list) {
			if (req->wb_page == page)
			if (nfs_page_to_folio(req) == folio)
				return req->wb_head;
		}
	}
@@ -375,14 +375,14 @@ pnfs_bucket_search_commit_reqs(struct pnfs_commit_bucket *buckets,
}

/* pnfs_generic_search_commit_reqs - Search lists in @cinfo for the head request
 *				   for @page
 *				   for @folio
 * @cinfo - commit info for current inode
 * @page - page to search for matching head request
 * @folio - page to search for matching head request
 *
 * Return: the head request if one is found, otherwise %NULL.
 */
struct nfs_page *
pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
struct nfs_page *pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo,
						 struct folio *folio)
{
	struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
	struct pnfs_commit_array *array;
@@ -390,7 +390,7 @@ pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page

	list_for_each_entry(array, &fl_cinfo->commits, cinfo_list) {
		req = pnfs_bucket_search_commit_reqs(array->buckets,
				array->nbuckets, page);
						     array->nbuckets, folio);
		if (req)
			return req;
	}
@@ -1180,7 +1180,7 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,

	nfs_request_add_commit_list_locked(req, list, cinfo);
	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
	nfs_mark_page_unstable(req->wb_page, cinfo);
	nfs_folio_mark_unstable(nfs_page_to_folio(req), cinfo);
	return;
out_resched:
	mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
+177 −173

File changed.

Preview size limit exceeded, changes collapsed.

Loading