NFS: Fix nfs_coalesce_size() to work with folios
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 19 Jan 2023 21:33:37 +0000 (16:33 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 14 Feb 2023 19:22:32 +0000 (14:22 -0500)
Use the helper folio_size() where appropriate.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/pagelist.c
include/linux/nfs_page.h

index 1744627222663f9b801de2482d2aed348028a15a..16c146ca7ffc67e2633ddc9542f970e280e5a0e2 100644 (file)
@@ -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);
 }
index d2ddc9a594c591c1fc20a710fbecb02105bb3f69..192071a6e5f6547f840ca8a37252390e900df6f3 100644 (file)
@@ -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
  */