CIFS: Find and reopen a file before get MTU credits in writepages
authorPavel Shilovsky <pshilov@microsoft.com>
Fri, 25 Jan 2019 23:23:36 +0000 (15:23 -0800)
committerSteve French <stfrench@microsoft.com>
Wed, 6 Mar 2019 00:10:04 +0000 (18:10 -0600)
Reorder finding and reopening a writable handle file and getting
MTU credits in writepages because we may be stuck on low credits
otherwise.

Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/file.c

index eaf5acba7f6bf69270689eb01869ea2b9fe5bbbd..4de7af04e732c3414d8b7d54f086ee2da56b333f 100644 (file)
@@ -2096,15 +2096,16 @@ wdata_send_pages(struct TCP_Server_Info *server, struct cifs_writedata *wdata,
        if (rc)
                goto send_pages_out;
 
-       if (wdata->cfile != NULL)
-               cifsFileInfo_put(wdata->cfile);
-       wdata->cfile = find_writable_file(CIFS_I(mapping->host), false);
        if (!wdata->cfile) {
-               cifs_dbg(VFS, "No writable handles for inode\n");
+               cifs_dbg(VFS, "No writable handle in writepages\n");
                rc = -EBADF;
        } else {
                wdata->pid = wdata->cfile->pid;
-               rc = server->ops->async_writev(wdata, cifs_writedata_release);
+               if (wdata->cfile->invalidHandle)
+                       rc = -EAGAIN;
+               else
+                       rc = server->ops->async_writev(wdata,
+                                                      cifs_writedata_release);
        }
 
 send_pages_out:
@@ -2117,11 +2118,13 @@ send_pages_out:
 static int cifs_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
 {
-       struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
+       struct inode *inode = mapping->host;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct TCP_Server_Info *server;
        bool done = false, scanned = false, range_whole = false;
        pgoff_t end, index;
        struct cifs_writedata *wdata;
+       struct cifsFileInfo *cfile = NULL;
        int rc = 0;
        int saved_rc = 0;
        unsigned int xid;
@@ -2152,6 +2155,11 @@ retry:
                struct cifs_credits credits_on_stack;
                struct cifs_credits *credits = &credits_on_stack;
 
+               if (cfile)
+                       cifsFileInfo_put(cfile);
+
+               cfile = find_writable_file(CIFS_I(inode), false);
+
                rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
                                                   &wsize, credits);
                if (rc != 0) {
@@ -2187,6 +2195,8 @@ retry:
                }
 
                wdata->credits = credits_on_stack;
+               wdata->cfile = cfile;
+               cfile = NULL;
 
                rc = wdata_send_pages(server, wdata, nr_pages, mapping, wbc);
 
@@ -2244,6 +2254,8 @@ retry:
        if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
                mapping->writeback_index = index;
 
+       if (cfile)
+               cifsFileInfo_put(cfile);
        free_xid(xid);
        return rc;
 }