2023-01-19 22:03:47

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH v2 04/18] NFS: Fix nfs_coalesce_size() to work with folios

From: Trond Myklebust <[email protected]>

Use the helper folio_size() where appropriate.

Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/pagelist.c | 28 +++++++++++++++++++---------
include/linux/nfs_page.h | 15 +++++++++++++++
2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 174462722266..16c146ca7ffc 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -1084,6 +1084,24 @@ static bool nfs_match_lock_context(const struct nfs_lock_context *l1,
return l1->lockowner == l2->lockowner;
}

+static bool nfs_page_is_contiguous(const struct nfs_page *prev,
+ const struct nfs_page *req)
+{
+ size_t prev_end = prev->wb_pgbase + prev->wb_bytes;
+
+ if (req_offset(req) != req_offset(prev) + prev->wb_bytes)
+ return false;
+ if (req->wb_pgbase == 0)
+ return prev_end == nfs_page_max_length(prev);
+ if (req->wb_pgbase == prev_end) {
+ struct folio *folio = nfs_page_to_folio(req);
+ if (folio)
+ return folio == nfs_page_to_folio(prev);
+ return req->wb_page == prev->wb_page;
+ }
+ return false;
+}
+
/**
* nfs_coalesce_size - test two requests for compatibility
* @prev: pointer to nfs_page
@@ -1112,16 +1130,8 @@ static unsigned int nfs_coalesce_size(struct nfs_page *prev,
!nfs_match_lock_context(req->wb_lock_context,
prev->wb_lock_context))
return 0;
- if (req_offset(req) != req_offset(prev) + prev->wb_bytes)
+ if (!nfs_page_is_contiguous(prev, req))
return 0;
- if (req->wb_page == prev->wb_page) {
- if (req->wb_pgbase != prev->wb_pgbase + prev->wb_bytes)
- return 0;
- } else {
- if (req->wb_pgbase != 0 ||
- prev->wb_pgbase + prev->wb_bytes != PAGE_SIZE)
- return 0;
- }
}
return pgio->pg_ops->pg_test(pgio, prev, req);
}
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index d2ddc9a594c5..192071a6e5f6 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -189,6 +189,21 @@ static inline struct page *nfs_page_to_page(const struct nfs_page *req,
return folio_page(folio, pgbase >> PAGE_SHIFT);
}

+/**
+ * nfs_page_max_length - Retrieve the maximum possible length for a request
+ * @req: pointer to a struct nfs_page
+ *
+ * Returns the maximum possible length of a request
+ */
+static inline size_t nfs_page_max_length(const struct nfs_page *req)
+{
+ struct folio *folio = nfs_page_to_folio(req);
+
+ if (folio == NULL)
+ return PAGE_SIZE;
+ return folio_size(folio);
+}
+
/*
* Lock the page of an asynchronous request
*/
--
2.39.0


2023-01-19 22:04:14

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH v2 05/18] NFS: Add a helper to convert a struct nfs_page into an inode

From: Trond Myklebust <[email protected]>

Replace all the open coded calls to page_file_mapping(req->wb_page)->host.

Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/pagelist.c | 2 +-
fs/nfs/write.c | 7 +++----
include/linux/nfs_page.h | 13 +++++++++++++
3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 16c146ca7ffc..4bdb570184f7 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -426,7 +426,7 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
* has extra ref from the write/commit path to handle handoff
* between write and commit lists. */
if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
- inode = page_file_mapping(req->wb_page)->host;
+ inode = nfs_page_to_inode(req);
set_bit(PG_INODE_REF, &req->wb_flags);
kref_get(&req->wb_kref);
atomic_long_inc(&NFS_I(inode)->nrequests);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 80c240e50952..1cbb92824791 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -421,7 +421,7 @@ static void nfs_set_page_writeback(struct page *page)

static void nfs_end_page_writeback(struct nfs_page *req)
{
- struct inode *inode = page_file_mapping(req->wb_page)->host;
+ struct inode *inode = nfs_page_to_inode(req);
struct nfs_server *nfss = NFS_SERVER(inode);
bool is_done;

@@ -592,8 +592,7 @@ nfs_lock_and_join_requests(struct page *page)

static void nfs_write_error(struct nfs_page *req, int error)
{
- trace_nfs_write_error(page_file_mapping(req->wb_page)->host, req,
- error);
+ trace_nfs_write_error(nfs_page_to_inode(req), req, error);
nfs_mapping_set_error(req->wb_page, error);
nfs_inode_remove_request(req);
nfs_end_page_writeback(req);
@@ -1420,7 +1419,7 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
*/
static void nfs_redirty_request(struct nfs_page *req)
{
- struct nfs_inode *nfsi = NFS_I(page_file_mapping(req->wb_page)->host);
+ struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req));

/* Bump the transmission count */
req->wb_nio++;
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 192071a6e5f6..b0b03ec4a209 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -189,6 +189,19 @@ static inline struct page *nfs_page_to_page(const struct nfs_page *req,
return folio_page(folio, pgbase >> PAGE_SHIFT);
}

+/**
+ * nfs_page_to_inode - Retrieve an inode for the request
+ * @req: pointer to a struct nfs_page
+ */
+static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
+{
+ struct folio *folio = nfs_page_to_folio(req);
+
+ if (folio == NULL)
+ return page_file_mapping(req->wb_page)->host;
+ return folio_file_mapping(folio)->host;
+}
+
/**
* nfs_page_max_length - Retrieve the maximum possible length for a request
* @req: pointer to a struct nfs_page
--
2.39.0