fuse: clean up condition for writepage sending
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 14 Jul 2020 12:45:41 +0000 (14:45 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Tue, 14 Jul 2020 12:45:41 +0000 (14:45 +0200)
fuse_writepages_fill uses following construction:

if (wpa && ap->num_pages &&
    (A || B || C)) {
        action;
} else if (wpa && D) {
        if (E) {
                the same action;
        }
}

 - ap->num_pages check is always true and can be removed

 - "if" and "else if" calls the same action and can be merged.

Move checking A, B, C, D, E conditions to a helper, add comments.

Original-patch-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c

index 63d52fe..a6a5aef 100644 (file)
@@ -2015,6 +2015,40 @@ static bool fuse_writepage_add(struct fuse_writepage_args *new_wpa,
        return false;
 }
 
+static bool fuse_writepage_need_send(struct fuse_conn *fc, struct page *page,
+                                    struct fuse_args_pages *ap,
+                                    struct fuse_fill_wb_data *data)
+{
+       WARN_ON(!ap->num_pages);
+
+       /*
+        * Being under writeback is unlikely but possible.  For example direct
+        * read to an mmaped fuse file will set the page dirty twice; once when
+        * the pages are faulted with get_user_pages(), and then after the read
+        * completed.
+        */
+       if (fuse_page_is_writeback(data->inode, page->index))
+               return true;
+
+       /* Reached max pages */
+       if (ap->num_pages == fc->max_pages)
+               return true;
+
+       /* Reached max write bytes */
+       if ((ap->num_pages + 1) * PAGE_SIZE > fc->max_write)
+               return true;
+
+       /* Discontinuity */
+       if (data->orig_pages[ap->num_pages - 1]->index + 1 != page->index)
+               return true;
+
+       /* Need to grow the pages array?  If so, did the expansion fail? */
+       if (ap->num_pages == data->max_pages && !fuse_pages_realloc(data))
+               return true;
+
+       return false;
+}
+
 static int fuse_writepages_fill(struct page *page,
                struct writeback_control *wbc, void *_data)
 {
@@ -2025,7 +2059,6 @@ static int fuse_writepages_fill(struct page *page,
        struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct page *tmp_page;
-       bool is_writeback;
        int err;
 
        if (!data->ff) {
@@ -2035,25 +2068,9 @@ static int fuse_writepages_fill(struct page *page,
                        goto out_unlock;
        }
 
-       /*
-        * Being under writeback is unlikely but possible.  For example direct
-        * read to an mmaped fuse file will set the page dirty twice; once when
-        * the pages are faulted with get_user_pages(), and then after the read
-        * completed.
-        */
-       is_writeback = fuse_page_is_writeback(inode, page->index);
-
-       if (wpa && ap->num_pages &&
-           (is_writeback || ap->num_pages == fc->max_pages ||
-            (ap->num_pages + 1) * PAGE_SIZE > fc->max_write ||
-            data->orig_pages[ap->num_pages - 1]->index + 1 != page->index)) {
+       if (wpa && fuse_writepage_need_send(fc, page, ap, data)) {
                fuse_writepages_send(data);
                data->wpa = NULL;
-       } else if (wpa && ap->num_pages == data->max_pages) {
-               if (!fuse_pages_realloc(data)) {
-                       fuse_writepages_send(data);
-                       data->wpa = NULL;
-               }
        }
 
        err = -ENOMEM;