]> git.baikalelectronics.ru Git - kernel.git/commitdiff
NFS: Try to join page groups before an O_DIRECT retransmission
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 31 Mar 2020 00:57:49 +0000 (20:57 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 1 Apr 2020 17:37:57 +0000 (13:37 -0400)
If we have to retransmit requests, try to join their page groups
first.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/direct.c
fs/nfs/write.c
include/linux/nfs_page.h

index 8074304fd5b4571558ebb344f1d47dea68baf03e..a57e7c72c7f475dbc5861dc8161a3cb00b3526d8 100644 (file)
@@ -505,6 +505,24 @@ out:
        return result;
 }
 
+static void
+nfs_direct_join_group(struct list_head *list, struct inode *inode)
+{
+       struct nfs_page *req, *next;
+
+       list_for_each_entry(req, list, wb_list) {
+               if (req->wb_head != req || req->wb_this_page == req)
+                       continue;
+               for (next = req->wb_this_page;
+                               next != req->wb_head;
+                               next = next->wb_this_page) {
+                       nfs_list_remove_request(next);
+                       nfs_release_request(next);
+               }
+               nfs_join_page_group(req, inode);
+       }
+}
+
 static void
 nfs_direct_write_scan_commit_list(struct inode *inode,
                                  struct list_head *list,
@@ -527,6 +545,8 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
        nfs_init_cinfo_from_dreq(&cinfo, dreq);
        nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
 
+       nfs_direct_join_group(&reqs, dreq->inode);
+
        dreq->count = 0;
        dreq->max_count = 0;
        list_for_each_entry(req, &reqs, wb_list)
index 63b64333c3ea3e79e744125857ced8e311cc64fa..df4b87c30ac9d6ad116dd4f948f5964bccf435ea 100644 (file)
@@ -501,7 +501,7 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list,
  * the (former) group.  All subrequests are removed from any write or commit
  * lists, unlinked from the group and destroyed.
  */
-static void
+void
 nfs_join_page_group(struct nfs_page *head, struct inode *inode)
 {
        struct nfs_page *subreq;
index 99198c039bd6a82a37bf70f3d649d8b4e5290f6c..c32c15216da34a485f9b996c70bec9e54dc1ec17 100644 (file)
@@ -141,6 +141,7 @@ extern      void nfs_unlock_request(struct nfs_page *req);
 extern void nfs_unlock_and_release_request(struct nfs_page *);
 extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
 extern int nfs_page_group_lock_subrequests(struct nfs_page *head);
+extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
 extern int nfs_page_group_lock(struct nfs_page *);
 extern void nfs_page_group_unlock(struct nfs_page *);
 extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);