Skip to content

Commit

Permalink
NFS: Convert buffered writes to use folios
Browse files Browse the repository at this point in the history
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: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
  • Loading branch information
Trond Myklebust authored and amschuma-ntap committed Feb 14, 2023
1 parent 5241060 commit 0c493b5
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 200 deletions.
14 changes: 9 additions & 5 deletions fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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;
Expand All @@ -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",
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 7 additions & 6 deletions fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
10 changes: 5 additions & 5 deletions fs/nfs/pnfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down
18 changes: 9 additions & 9 deletions fs/nfs/pnfs_nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -363,34 +363,34 @@ 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;
}
}
return NULL;
}

/* 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;
struct nfs_page *req;

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;
}
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 0c493b5

Please sign in to comment.