summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilov@microsoft.com>2019-01-25 18:23:36 -0500
committerSteve French <stfrench@microsoft.com>2019-03-05 19:10:04 -0500
commitc7d38dbe7d3851e52f6117d9bbbf6865066b81d9 (patch)
treecdd7cc5461580e92addfdc0735bc3470d98fa362 /fs/cifs
parent3e9529944d4177bd3a0952f4e7fe4f76c0f9bf6f (diff)
CIFS: Find and reopen a file before get MTU credits in writepages
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>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/file.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index eaf5acba7f6b..4de7af04e732 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2096,15 +2096,16 @@ wdata_send_pages(struct TCP_Server_Info *server, struct cifs_writedata *wdata,
2096 if (rc) 2096 if (rc)
2097 goto send_pages_out; 2097 goto send_pages_out;
2098 2098
2099 if (wdata->cfile != NULL)
2100 cifsFileInfo_put(wdata->cfile);
2101 wdata->cfile = find_writable_file(CIFS_I(mapping->host), false);
2102 if (!wdata->cfile) { 2099 if (!wdata->cfile) {
2103 cifs_dbg(VFS, "No writable handles for inode\n"); 2100 cifs_dbg(VFS, "No writable handle in writepages\n");
2104 rc = -EBADF; 2101 rc = -EBADF;
2105 } else { 2102 } else {
2106 wdata->pid = wdata->cfile->pid; 2103 wdata->pid = wdata->cfile->pid;
2107 rc = server->ops->async_writev(wdata, cifs_writedata_release); 2104 if (wdata->cfile->invalidHandle)
2105 rc = -EAGAIN;
2106 else
2107 rc = server->ops->async_writev(wdata,
2108 cifs_writedata_release);
2108 } 2109 }
2109 2110
2110send_pages_out: 2111send_pages_out:
@@ -2117,11 +2118,13 @@ send_pages_out:
2117static int cifs_writepages(struct address_space *mapping, 2118static int cifs_writepages(struct address_space *mapping,
2118 struct writeback_control *wbc) 2119 struct writeback_control *wbc)
2119{ 2120{
2120 struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb); 2121 struct inode *inode = mapping->host;
2122 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2121 struct TCP_Server_Info *server; 2123 struct TCP_Server_Info *server;
2122 bool done = false, scanned = false, range_whole = false; 2124 bool done = false, scanned = false, range_whole = false;
2123 pgoff_t end, index; 2125 pgoff_t end, index;
2124 struct cifs_writedata *wdata; 2126 struct cifs_writedata *wdata;
2127 struct cifsFileInfo *cfile = NULL;
2125 int rc = 0; 2128 int rc = 0;
2126 int saved_rc = 0; 2129 int saved_rc = 0;
2127 unsigned int xid; 2130 unsigned int xid;
@@ -2152,6 +2155,11 @@ retry:
2152 struct cifs_credits credits_on_stack; 2155 struct cifs_credits credits_on_stack;
2153 struct cifs_credits *credits = &credits_on_stack; 2156 struct cifs_credits *credits = &credits_on_stack;
2154 2157
2158 if (cfile)
2159 cifsFileInfo_put(cfile);
2160
2161 cfile = find_writable_file(CIFS_I(inode), false);
2162
2155 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2163 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2156 &wsize, credits); 2164 &wsize, credits);
2157 if (rc != 0) { 2165 if (rc != 0) {
@@ -2187,6 +2195,8 @@ retry:
2187 } 2195 }
2188 2196
2189 wdata->credits = credits_on_stack; 2197 wdata->credits = credits_on_stack;
2198 wdata->cfile = cfile;
2199 cfile = NULL;
2190 2200
2191 rc = wdata_send_pages(server, wdata, nr_pages, mapping, wbc); 2201 rc = wdata_send_pages(server, wdata, nr_pages, mapping, wbc);
2192 2202
@@ -2244,6 +2254,8 @@ retry:
2244 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 2254 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
2245 mapping->writeback_index = index; 2255 mapping->writeback_index = index;
2246 2256
2257 if (cfile)
2258 cifsFileInfo_put(cfile);
2247 free_xid(xid); 2259 free_xid(xid);
2248 return rc; 2260 return rc;
2249} 2261}