diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2014-06-19 08:15:16 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2014-08-02 02:23:02 -0400 |
commit | 66231a47965c551d3056d5104f8b06688065748c (patch) | |
tree | e0cd7960963fd8cdec2833724be99c29b6aeab8c /fs/cifs/file.c | |
parent | 90ac1387c2dfcd9b4bd302fce03b9ddff73d0093 (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.c | 25 |
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, | |||
2058 | retry: | 2056 | retry: |
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; |