From: trondmy@kernel.org
To: Anna Schumaker <Anna.Schumaker@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH v2 12/18] NFS: Convert nfs_write_begin/end to use folios
Date: Thu, 19 Jan 2023 16:33:45 -0500 [thread overview]
Message-ID: <20230119213351.443388-13-trondmy@kernel.org> (raw)
In-Reply-To: <20230119213351.443388-12-trondmy@kernel.org>
From: Trond Myklebust <trond.myklebust@hammerspace.com>
Add a helper nfs_folio_grab_cache_write_begin() that can call
__filemap_get_folio() directly with the appropriate parameters.
Since write_begin()/write_end() take struct page arguments, just pass
the folio->page back for now.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
fs/nfs/file.c | 75 ++++++++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 34 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 9fbe27214da0..39ee7fb3f79f 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -276,27 +276,28 @@ EXPORT_SYMBOL_GPL(nfs_file_fsync);
* and that the new data won't completely replace the old data in
* that range of the file.
*/
-static bool nfs_full_page_write(struct page *page, loff_t pos, unsigned int len)
+static bool nfs_folio_is_full_write(struct folio *folio, loff_t pos,
+ unsigned int len)
{
- unsigned int pglen = nfs_page_length(page);
- unsigned int offset = pos & (PAGE_SIZE - 1);
+ unsigned int pglen = nfs_folio_length(folio);
+ unsigned int offset = offset_in_folio(folio, pos);
unsigned int end = offset + len;
return !pglen || (end >= pglen && !offset);
}
-static bool nfs_want_read_modify_write(struct file *file, struct page *page,
- loff_t pos, unsigned int len)
+static bool nfs_want_read_modify_write(struct file *file, struct folio *folio,
+ loff_t pos, unsigned int len)
{
/*
* Up-to-date pages, those with ongoing or full-page write
* don't need read/modify/write
*/
- if (PageUptodate(page) || PagePrivate(page) ||
- nfs_full_page_write(page, pos, len))
+ if (folio_test_uptodate(folio) || folio_test_private(folio) ||
+ nfs_folio_is_full_write(folio, pos, len))
return false;
- if (pnfs_ld_read_whole_page(file->f_mapping->host))
+ if (pnfs_ld_read_whole_page(file_inode(file)))
return true;
/* Open for reading too? */
if (file->f_mode & FMODE_READ)
@@ -304,6 +305,15 @@ static bool nfs_want_read_modify_write(struct file *file, struct page *page,
return false;
}
+static struct folio *
+nfs_folio_grab_cache_write_begin(struct address_space *mapping, pgoff_t index)
+{
+ unsigned fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE;
+
+ return __filemap_get_folio(mapping, index, fgp_flags,
+ mapping_gfp_mask(mapping));
+}
+
/*
* This does the "real" work of the write. We must allocate and lock the
* page to be sent back to the generic routine, which then copies the
@@ -313,34 +323,31 @@ static bool nfs_want_read_modify_write(struct file *file, struct page *page,
* increment the page use counts until he is done with the page.
*/
static int nfs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct page **pagep, void **fsdata)
+ loff_t pos, unsigned len, struct page **pagep,
+ void **fsdata)
{
- int ret;
- pgoff_t index = pos >> PAGE_SHIFT;
- struct page *page;
struct folio *folio;
int once_thru = 0;
+ int ret;
dfprintk(PAGECACHE, "NFS: write_begin(%pD2(%lu), %u@%lld)\n",
file, mapping->host->i_ino, len, (long long) pos);
start:
- page = grab_cache_page_write_begin(mapping, index);
- if (!page)
+ folio = nfs_folio_grab_cache_write_begin(mapping, pos >> PAGE_SHIFT);
+ if (!folio)
return -ENOMEM;
- *pagep = page;
- folio = page_folio(page);
+ *pagep = &folio->page;
ret = nfs_flush_incompatible(file, folio);
if (ret) {
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
} else if (!once_thru &&
- nfs_want_read_modify_write(file, page, pos, len)) {
+ nfs_want_read_modify_write(file, folio, pos, len)) {
once_thru = 1;
ret = nfs_read_folio(file, folio);
- put_page(page);
+ folio_put(folio);
if (!ret)
goto start;
}
@@ -348,12 +355,12 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
}
static int nfs_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- unsigned offset = pos & (PAGE_SIZE - 1);
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct folio *folio = page_folio(page);
+ unsigned offset = offset_in_folio(folio, pos);
int status;
dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n",
@@ -363,26 +370,26 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
* Zero any uninitialised parts of the page, and then mark the page
* as up to date if it turns out that we're extending the file.
*/
- if (!PageUptodate(page)) {
- unsigned pglen = nfs_page_length(page);
+ if (!folio_test_uptodate(folio)) {
+ size_t fsize = folio_size(folio);
+ unsigned pglen = nfs_folio_length(folio);
unsigned end = offset + copied;
if (pglen == 0) {
- zero_user_segments(page, 0, offset,
- end, PAGE_SIZE);
- SetPageUptodate(page);
+ folio_zero_segments(folio, 0, offset, end, fsize);
+ folio_mark_uptodate(folio);
} else if (end >= pglen) {
- zero_user_segment(page, end, PAGE_SIZE);
+ folio_zero_segment(folio, end, fsize);
if (offset == 0)
- SetPageUptodate(page);
+ folio_mark_uptodate(folio);
} else
- zero_user_segment(page, pglen, PAGE_SIZE);
+ folio_zero_segment(folio, pglen, fsize);
}
status = nfs_update_folio(file, folio, offset, copied);
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
if (status < 0)
return status;
--
2.39.0
next prev parent reply other threads:[~2023-01-19 22:03 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-19 21:33 [PATCH v2 00/18] Initial conversion of NFS basic I/O to use folios trondmy
2023-01-19 21:33 ` [PATCH v2 01/18] NFS: Fix for xfstests generic/208 trondmy
2023-01-19 21:33 ` [PATCH v2 02/18] NFS: Add basic functionality for tracking folios in struct nfs_page trondmy
2023-01-19 21:33 ` [PATCH v2 03/18] NFS: Support folios in nfs_generic_pgio() trondmy
2023-01-19 21:33 ` [PATCH v2 04/18] NFS: Fix nfs_coalesce_size() to work with folios trondmy
2023-01-19 21:33 ` [PATCH v2 05/18] NFS: Add a helper to convert a struct nfs_page into an inode trondmy
2023-01-19 21:33 ` [PATCH v2 06/18] NFS: Convert the remaining pagelist helper functions to support folios trondmy
2023-01-19 21:33 ` [PATCH v2 07/18] NFS: Add a helper nfs_wb_folio() trondmy
2023-01-19 21:33 ` [PATCH v2 08/18] NFS: Convert buffered reads to use folios trondmy
2023-01-19 21:33 ` [PATCH v2 09/18] NFS: Convert the function nfs_wb_page() " trondmy
2023-01-19 21:33 ` [PATCH v2 10/18] NFS: Convert buffered writes " trondmy
2023-01-19 21:33 ` [PATCH v2 11/18] NFS: Remove unused function nfs_wb_page() trondmy
2023-01-19 21:33 ` trondmy [this message]
2023-01-19 21:33 ` [PATCH v2 13/18] NFS: Fix up nfs_vm_page_mkwrite() for folios trondmy
2023-01-19 21:33 ` [PATCH v2 14/18] NFS: Clean up O_DIRECT request allocation trondmy
2023-01-19 21:33 ` [PATCH v2 15/18] NFS: fix up nfs_release_folio() to try to release the page trondmy
2023-01-19 21:33 ` [PATCH v2 16/18] NFS: Enable tracing of nfs_invalidate_folio() and nfs_launder_folio() trondmy
2023-01-19 21:33 ` [PATCH v2 17/18] NFS: Improve tracing of nfs_wb_folio() trondmy
2023-01-19 21:33 ` [PATCH v2 18/18] NFS: Remove unnecessary check in nfs_read_folio() trondmy
2023-02-23 13:22 ` Matthew Wilcox
2023-02-23 13:43 ` Dan Carpenter
2023-01-24 16:07 ` [PATCH v2 00/18] Initial conversion of NFS basic I/O to use folios Olga Kornievskaia
2023-01-24 16:41 ` Trond Myklebust
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230119213351.443388-13-trondmy@kernel.org \
--to=trondmy@kernel.org \
--cc=Anna.Schumaker@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.