by filling the output buffer with a data got from a partially received
response and requesting the remaining data from the server.

Signed-off-by: Pavel Shilovsky <[email protected]>
---
 fs/cifs/file.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 6896cb5..d7246cb 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3029,13 +3029,30 @@ again:
                        else if (rdata->result == -EAGAIN) {
                                /* resend call if it's a retryable error */
                                struct list_head tmp_list;
+                               unsigned int got_bytes = rdata->got_bytes;
 
                                list_del_init(&rdata->list);
                                INIT_LIST_HEAD(&tmp_list);
 
-                               rc = cifs_send_async_read(rdata->offset,
-                                               rdata->bytes, rdata->cfile,
-                                               cifs_sb, &tmp_list);
+                               /*
+                                * Got a part of data and then reconnect has
+                                * happened -- discard anything left and return
+                                * a short read.
+                                */
+                               if (got_bytes && got_bytes < rdata->bytes) {
+                                       rc = cifs_readdata_to_iov(rdata, to);
+                                       if (rc) {
+                                               kref_put(&rdata->refcount,
+                                               cifs_uncached_readdata_release);
+                                               continue;
+                                       }
+                               }
+
+                               rc = cifs_send_async_read(
+                                               rdata->offset + got_bytes,
+                                               rdata->bytes - got_bytes,
+                                               rdata->cfile, cifs_sb,
+                                               &tmp_list);
 
                                list_splice(&tmp_list, &rdata_list);
 
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to