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: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
fb8a3e5255
commit
d913ed17f0
3 changed files with 32 additions and 3 deletions
|
@ -1561,6 +1561,12 @@ cifs_readv_callback(struct mid_q_entry *mid)
|
||||||
case MID_REQUEST_SUBMITTED:
|
case MID_REQUEST_SUBMITTED:
|
||||||
case MID_RETRY_NEEDED:
|
case MID_RETRY_NEEDED:
|
||||||
rdata->result = -EAGAIN;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
rdata->result = -EIO;
|
rdata->result = -EIO;
|
||||||
|
|
|
@ -3030,13 +3030,30 @@ again:
|
||||||
else if (rdata->result == -EAGAIN) {
|
else if (rdata->result == -EAGAIN) {
|
||||||
/* resend call if it's a retryable error */
|
/* resend call if it's a retryable error */
|
||||||
struct list_head tmp_list;
|
struct list_head tmp_list;
|
||||||
|
unsigned int got_bytes = rdata->got_bytes;
|
||||||
|
|
||||||
list_del_init(&rdata->list);
|
list_del_init(&rdata->list);
|
||||||
INIT_LIST_HEAD(&tmp_list);
|
INIT_LIST_HEAD(&tmp_list);
|
||||||
|
|
||||||
rc = cifs_send_async_read(rdata->offset,
|
/*
|
||||||
rdata->bytes, rdata->cfile,
|
* Got a part of data and then reconnect has
|
||||||
cifs_sb, &tmp_list);
|
* 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);
|
list_splice(&tmp_list, &rdata_list);
|
||||||
|
|
||||||
|
|
|
@ -1729,6 +1729,12 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
||||||
case MID_REQUEST_SUBMITTED:
|
case MID_REQUEST_SUBMITTED:
|
||||||
case MID_RETRY_NEEDED:
|
case MID_RETRY_NEEDED:
|
||||||
rdata->result = -EAGAIN;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
if (rdata->result != -ENODATA)
|
if (rdata->result != -ENODATA)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue