Commit d913ed17 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French

CIFS: Optimize cifs_user_read() in a short read case on reconnects

by filling the output buffer with a data got from a partially received
response and requesting the remaining data from the server. This is
suitable for non-signed connections.
Signed-off-by: default avatarPavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent fb8a3e52
......@@ -1561,6 +1561,12 @@ cifs_readv_callback(struct mid_q_entry *mid)
case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED:
rdata->result = -EAGAIN;
if (server->sign && rdata->got_bytes)
/* reset bytes number since we can not check a sign */
rdata->got_bytes = 0;
/* FIXME: should this be counted toward the initiating task? */
task_io_account_read(rdata->got_bytes);
cifs_stats_bytes_read(tcon, rdata->got_bytes);
break;
default:
rdata->result = -EIO;
......
......@@ -3030,13 +3030,30 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
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 -- fill the buffer and continue
* reading.
*/
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);
......
......@@ -1729,6 +1729,12 @@ smb2_readv_callback(struct mid_q_entry *mid)
case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED:
rdata->result = -EAGAIN;
if (server->sign && rdata->got_bytes)
/* reset bytes number since we can not check a sign */
rdata->got_bytes = 0;
/* FIXME: should this be counted toward the initiating task? */
task_io_account_read(rdata->got_bytes);
cifs_stats_bytes_read(tcon, rdata->got_bytes);
break;
default:
if (rdata->result != -ENODATA)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment