diff mbox

[6/7] CIFS: Optimize cifs_user_read() in a short read case on reconnects

Message ID 1404984647-8710-7-git-send-email-pshilovsky@samba.org (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Shilovsky July 10, 2014, 9:30 a.m. UTC
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 <pshilovsky@samba.org>
---
 fs/cifs/file.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Comments

Pavel Shilovsky July 10, 2014, 9:40 a.m. UTC | #1
2014-07-10 13:30 GMT+04:00 Pavel Shilovsky <pshilovsky@samba.org>:
> 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 <pshilovsky@samba.org>
> ---
>  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.
> +                                */
                                     ^^^
Ah, wrong version of the comment is posted. Sorry. The right one:
+                               /*
+                                * Got a part of data and then reconnect has
+                                * happened -- fill the buffer and continue
+                                * reading.
+                                */

will repost this after a feedback.

> +                               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
>
diff mbox

Patch

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);