summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2014-06-19 08:15:16 -0400
committerSteve French <smfrench@gmail.com>2014-08-02 02:23:02 -0400
commit66231a47965c551d3056d5104f8b06688065748c (patch)
treee0cd7960963fd8cdec2833724be99c29b6aeab8c /fs/cifs/file.c
parent90ac1387c2dfcd9b4bd302fce03b9ddff73d0093 (diff)
CIFS: Fix wsize usage in writepages
If a server change maximum buffer size for write (wsize) requests on reconnect we can fail on repeating with a big size buffer on -EAGAIN error in writepages. Fix this by checking wsize all the time before repeating request in writepages. Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0064d38fdb76..ff4a9c3fe421 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2009,19 +2009,17 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2009 (loff_t)PAGE_CACHE_SIZE); 2009 (loff_t)PAGE_CACHE_SIZE);
2010 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + wdata->tailsz; 2010 wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + wdata->tailsz;
2011 2011
2012 do { 2012 if (wdata->cfile != NULL)
2013 if (wdata->cfile != NULL) 2013 cifsFileInfo_put(wdata->cfile);
2014 cifsFileInfo_put(wdata->cfile); 2014 wdata->cfile = find_writable_file(CIFS_I(mapping->host), false);
2015 wdata->cfile = find_writable_file(CIFS_I(mapping->host), false); 2015 if (!wdata->cfile) {
2016 if (!wdata->cfile) { 2016 cifs_dbg(VFS, "No writable handles for inode\n");
2017 cifs_dbg(VFS, "No writable handles for inode\n"); 2017 rc = -EBADF;
2018 rc = -EBADF; 2018 } else {
2019 break;
2020 }
2021 wdata->pid = wdata->cfile->pid; 2019 wdata->pid = wdata->cfile->pid;
2022 server = tlink_tcon(wdata->cfile->tlink)->ses->server; 2020 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2023 rc = server->ops->async_writev(wdata, cifs_writedata_release); 2021 rc = server->ops->async_writev(wdata, cifs_writedata_release);
2024 } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); 2022 }
2025 2023
2026 for (i = 0; i < nr_pages; ++i) 2024 for (i = 0; i < nr_pages; ++i)
2027 unlock_page(wdata->pages[i]); 2025 unlock_page(wdata->pages[i]);
@@ -2058,7 +2056,7 @@ static int cifs_writepages(struct address_space *mapping,
2058retry: 2056retry:
2059 while (!done && index <= end) { 2057 while (!done && index <= end) {
2060 unsigned int i, nr_pages, found_pages; 2058 unsigned int i, nr_pages, found_pages;
2061 pgoff_t next = 0, tofind; 2059 pgoff_t next = 0, tofind, saved_index = index;
2062 2060
2063 tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1, 2061 tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
2064 end - index) + 1; 2062 end - index) + 1;
@@ -2102,6 +2100,11 @@ retry:
2102 } 2100 }
2103 kref_put(&wdata->refcount, cifs_writedata_release); 2101 kref_put(&wdata->refcount, cifs_writedata_release);
2104 2102
2103 if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN) {
2104 index = saved_index;
2105 continue;
2106 }
2107
2105 wbc->nr_to_write -= nr_pages; 2108 wbc->nr_to_write -= nr_pages;
2106 if (wbc->nr_to_write <= 0) 2109 if (wbc->nr_to_write <= 0)
2107 done = true; 2110 done = true;