mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
cifs: Fix SMB1 readv/writev callback in the same way as SMB2/3
Port a number of SMB2/3 async readv/writev fixes to the SMB1 transport: commita88d609036
cifs: Don't advance the I/O iterator before terminating subrequest commitce5291e560
cifs: Defer read completion commit1da29f2c39
netfs, cifs: Fix handling of short DIO read Fixes:3ee1a1fc39
("cifs: Cut over to using netfslib") Signed-off-by: David Howells <dhowells@redhat.com> Reported-by: Steve French <stfrench@microsoft.com> Reviewed-by: Paulo Alcantara <pc@manguebit.com> cc: Jeff Layton <jlayton@kernel.org> cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
517b58c1f9
commit
a68c74865f
1 changed files with 46 additions and 8 deletions
|
@ -1261,16 +1261,32 @@ openRetry:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cifs_readv_worker(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct cifs_io_subrequest *rdata =
|
||||||
|
container_of(work, struct cifs_io_subrequest, subreq.work);
|
||||||
|
|
||||||
|
netfs_subreq_terminated(&rdata->subreq,
|
||||||
|
(rdata->result == 0 || rdata->result == -EAGAIN) ?
|
||||||
|
rdata->got_bytes : rdata->result, true);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cifs_readv_callback(struct mid_q_entry *mid)
|
cifs_readv_callback(struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||||
|
struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
|
||||||
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
|
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
|
||||||
struct TCP_Server_Info *server = tcon->ses->server;
|
struct TCP_Server_Info *server = tcon->ses->server;
|
||||||
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
||||||
.rq_nvec = 2,
|
.rq_nvec = 2,
|
||||||
.rq_iter = rdata->subreq.io_iter };
|
.rq_iter = rdata->subreq.io_iter };
|
||||||
struct cifs_credits credits = { .value = 1, .instance = 0 };
|
struct cifs_credits credits = {
|
||||||
|
.value = 1,
|
||||||
|
.instance = 0,
|
||||||
|
.rreq_debug_id = rdata->rreq->debug_id,
|
||||||
|
.rreq_debug_index = rdata->subreq.debug_index,
|
||||||
|
};
|
||||||
|
|
||||||
cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
|
cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
|
||||||
__func__, mid->mid, mid->mid_state, rdata->result,
|
__func__, mid->mid, mid->mid_state, rdata->result,
|
||||||
|
@ -1282,6 +1298,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
|
||||||
if (server->sign) {
|
if (server->sign) {
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
|
||||||
rc = cifs_verify_signature(&rqst, server,
|
rc = cifs_verify_signature(&rqst, server,
|
||||||
mid->sequence_number);
|
mid->sequence_number);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -1306,13 +1323,21 @@ cifs_readv_callback(struct mid_q_entry *mid)
|
||||||
rdata->result = -EIO;
|
rdata->result = -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rdata->result == 0 || rdata->result == -EAGAIN)
|
if (rdata->result == -ENODATA) {
|
||||||
iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
|
__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
|
||||||
|
rdata->result = 0;
|
||||||
|
} else {
|
||||||
|
if (rdata->got_bytes < rdata->actual_len &&
|
||||||
|
rdata->subreq.start + rdata->subreq.transferred + rdata->got_bytes ==
|
||||||
|
ictx->remote_i_size) {
|
||||||
|
__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
|
||||||
|
rdata->result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rdata->credits.value = 0;
|
rdata->credits.value = 0;
|
||||||
netfs_subreq_terminated(&rdata->subreq,
|
INIT_WORK(&rdata->subreq.work, cifs_readv_worker);
|
||||||
(rdata->result == 0 || rdata->result == -EAGAIN) ?
|
queue_work(cifsiod_wq, &rdata->subreq.work);
|
||||||
rdata->got_bytes : rdata->result,
|
|
||||||
false);
|
|
||||||
release_mid(mid);
|
release_mid(mid);
|
||||||
add_credits(server, &credits, 0);
|
add_credits(server, &credits, 0);
|
||||||
}
|
}
|
||||||
|
@ -1619,9 +1644,15 @@ static void
|
||||||
cifs_writev_callback(struct mid_q_entry *mid)
|
cifs_writev_callback(struct mid_q_entry *mid)
|
||||||
{
|
{
|
||||||
struct cifs_io_subrequest *wdata = mid->callback_data;
|
struct cifs_io_subrequest *wdata = mid->callback_data;
|
||||||
|
struct TCP_Server_Info *server = wdata->server;
|
||||||
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
|
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
|
||||||
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
|
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
|
||||||
struct cifs_credits credits = { .value = 1, .instance = 0 };
|
struct cifs_credits credits = {
|
||||||
|
.value = 1,
|
||||||
|
.instance = 0,
|
||||||
|
.rreq_debug_id = wdata->rreq->debug_id,
|
||||||
|
.rreq_debug_index = wdata->subreq.debug_index,
|
||||||
|
};
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
size_t written;
|
size_t written;
|
||||||
|
|
||||||
|
@ -1657,9 +1688,16 @@ cifs_writev_callback(struct mid_q_entry *mid)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index,
|
||||||
|
wdata->credits.value,
|
||||||
|
server->credits, server->in_flight,
|
||||||
|
0, cifs_trace_rw_credits_write_response_clear);
|
||||||
wdata->credits.value = 0;
|
wdata->credits.value = 0;
|
||||||
cifs_write_subrequest_terminated(wdata, result, true);
|
cifs_write_subrequest_terminated(wdata, result, true);
|
||||||
release_mid(mid);
|
release_mid(mid);
|
||||||
|
trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
|
||||||
|
server->credits, server->in_flight,
|
||||||
|
credits.value, cifs_trace_rw_credits_write_response_add);
|
||||||
add_credits(tcon->ses->server, &credits, 0);
|
add_credits(tcon->ses->server, &credits, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue