Skip to content

Commit a68c748

Browse files
dhowellssmfrench
authored andcommitted
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: commit a88d609 cifs: Don't advance the I/O iterator before terminating subrequest commit ce5291e cifs: Defer read completion commit 1da29f2 netfs, cifs: Fix handling of short DIO read Fixes: 3ee1a1f ("cifs: Cut over to using netfslib") Signed-off-by: David Howells <[email protected]> Reported-by: Steve French <[email protected]> Reviewed-by: Paulo Alcantara <[email protected]> cc: Jeff Layton <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected] Signed-off-by: Steve French <[email protected]>
1 parent 517b58c commit a68c748

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

fs/smb/client/cifssmb.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,16 +1261,32 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
12611261
return rc;
12621262
}
12631263

1264+
static void cifs_readv_worker(struct work_struct *work)
1265+
{
1266+
struct cifs_io_subrequest *rdata =
1267+
container_of(work, struct cifs_io_subrequest, subreq.work);
1268+
1269+
netfs_subreq_terminated(&rdata->subreq,
1270+
(rdata->result == 0 || rdata->result == -EAGAIN) ?
1271+
rdata->got_bytes : rdata->result, true);
1272+
}
1273+
12641274
static void
12651275
cifs_readv_callback(struct mid_q_entry *mid)
12661276
{
12671277
struct cifs_io_subrequest *rdata = mid->callback_data;
1278+
struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
12681279
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
12691280
struct TCP_Server_Info *server = tcon->ses->server;
12701281
struct smb_rqst rqst = { .rq_iov = rdata->iov,
12711282
.rq_nvec = 2,
12721283
.rq_iter = rdata->subreq.io_iter };
1273-
struct cifs_credits credits = { .value = 1, .instance = 0 };
1284+
struct cifs_credits credits = {
1285+
.value = 1,
1286+
.instance = 0,
1287+
.rreq_debug_id = rdata->rreq->debug_id,
1288+
.rreq_debug_index = rdata->subreq.debug_index,
1289+
};
12741290

12751291
cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
12761292
__func__, mid->mid, mid->mid_state, rdata->result,
@@ -1282,6 +1298,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
12821298
if (server->sign) {
12831299
int rc = 0;
12841300

1301+
iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
12851302
rc = cifs_verify_signature(&rqst, server,
12861303
mid->sequence_number);
12871304
if (rc)
@@ -1306,13 +1323,21 @@ cifs_readv_callback(struct mid_q_entry *mid)
13061323
rdata->result = -EIO;
13071324
}
13081325

1309-
if (rdata->result == 0 || rdata->result == -EAGAIN)
1310-
iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
1326+
if (rdata->result == -ENODATA) {
1327+
__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1328+
rdata->result = 0;
1329+
} else {
1330+
if (rdata->got_bytes < rdata->actual_len &&
1331+
rdata->subreq.start + rdata->subreq.transferred + rdata->got_bytes ==
1332+
ictx->remote_i_size) {
1333+
__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
1334+
rdata->result = 0;
1335+
}
1336+
}
1337+
13111338
rdata->credits.value = 0;
1312-
netfs_subreq_terminated(&rdata->subreq,
1313-
(rdata->result == 0 || rdata->result == -EAGAIN) ?
1314-
rdata->got_bytes : rdata->result,
1315-
false);
1339+
INIT_WORK(&rdata->subreq.work, cifs_readv_worker);
1340+
queue_work(cifsiod_wq, &rdata->subreq.work);
13161341
release_mid(mid);
13171342
add_credits(server, &credits, 0);
13181343
}
@@ -1619,9 +1644,15 @@ static void
16191644
cifs_writev_callback(struct mid_q_entry *mid)
16201645
{
16211646
struct cifs_io_subrequest *wdata = mid->callback_data;
1647+
struct TCP_Server_Info *server = wdata->server;
16221648
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
16231649
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1624-
struct cifs_credits credits = { .value = 1, .instance = 0 };
1650+
struct cifs_credits credits = {
1651+
.value = 1,
1652+
.instance = 0,
1653+
.rreq_debug_id = wdata->rreq->debug_id,
1654+
.rreq_debug_index = wdata->subreq.debug_index,
1655+
};
16251656
ssize_t result;
16261657
size_t written;
16271658

@@ -1657,9 +1688,16 @@ cifs_writev_callback(struct mid_q_entry *mid)
16571688
break;
16581689
}
16591690

1691+
trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index,
1692+
wdata->credits.value,
1693+
server->credits, server->in_flight,
1694+
0, cifs_trace_rw_credits_write_response_clear);
16601695
wdata->credits.value = 0;
16611696
cifs_write_subrequest_terminated(wdata, result, true);
16621697
release_mid(mid);
1698+
trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
1699+
server->credits, server->in_flight,
1700+
credits.value, cifs_trace_rw_credits_write_response_add);
16631701
add_credits(tcon->ses->server, &credits, 0);
16641702
}
16651703

0 commit comments

Comments
 (0)