aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2014-06-25 08:19:02 -0400
committerSteve French <smfrench@gmail.com>2014-08-02 02:23:03 -0400
commite374d90f8a7693f24635bca9e5d56f3775bb36e2 (patch)
tree5be53f15accc65ab4ea25ccc8823540ad6c7aa3f /fs/cifs
parent25f402598d2c8f0808d93715ad33e43b265c1604 (diff)
CIFS: Fix rsize usage for sync read
If a server changes maximum buffer size for read requests (rsize) on reconnect we can fail on repeating with a big size buffer on -EAGAIN error in cifs_read. Fix this by checking rsize all the time before repeating requests. 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')
-rw-r--r--fs/cifs/file.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index bbc38594b39a..00b2a254ff1c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3148,18 +3148,19 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
3148 3148
3149 for (total_read = 0, cur_offset = read_data; read_size > total_read; 3149 for (total_read = 0, cur_offset = read_data; read_size > total_read;
3150 total_read += bytes_read, cur_offset += bytes_read) { 3150 total_read += bytes_read, cur_offset += bytes_read) {
3151 current_read_size = min_t(uint, read_size - total_read, rsize); 3151 do {
3152 /* 3152 current_read_size = min_t(uint, read_size - total_read,
3153 * For windows me and 9x we do not want to request more than it 3153 rsize);
3154 * negotiated since it will refuse the read then. 3154 /*
3155 */ 3155 * For windows me and 9x we do not want to request more
3156 if ((tcon->ses) && !(tcon->ses->capabilities & 3156 * than it negotiated since it will refuse the read
3157 * then.
3158 */
3159 if ((tcon->ses) && !(tcon->ses->capabilities &
3157 tcon->ses->server->vals->cap_large_files)) { 3160 tcon->ses->server->vals->cap_large_files)) {
3158 current_read_size = min_t(uint, current_read_size, 3161 current_read_size = min_t(uint,
3159 CIFSMaxBufSize); 3162 current_read_size, CIFSMaxBufSize);
3160 } 3163 }
3161 rc = -EAGAIN;
3162 while (rc == -EAGAIN) {
3163 if (open_file->invalidHandle) { 3164 if (open_file->invalidHandle) {
3164 rc = cifs_reopen_file(open_file, true); 3165 rc = cifs_reopen_file(open_file, true);
3165 if (rc != 0) 3166 if (rc != 0)
@@ -3172,7 +3173,8 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
3172 rc = server->ops->sync_read(xid, open_file, &io_parms, 3173 rc = server->ops->sync_read(xid, open_file, &io_parms,
3173 &bytes_read, &cur_offset, 3174 &bytes_read, &cur_offset,
3174 &buf_type); 3175 &buf_type);
3175 } 3176 } while (rc == -EAGAIN);
3177
3176 if (rc || (bytes_read == 0)) { 3178 if (rc || (bytes_read == 0)) {
3177 if (total_read) { 3179 if (total_read) {
3178 break; 3180 break;