Skip to content

Commit 5e90aa2

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: fix max_credits implementation
The current implementation of max_credits on the client does not work because the CreditRequest logic for several commands does not take max_credits into account. Still, we can end up asking the server for more credits, depending on the number of credits in flight. For this, we need to limit the credits while parsing the responses too. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 2991b77 commit 5e90aa2

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

fs/smb/client/smb2ops.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ static int
3434
change_conf(struct TCP_Server_Info *server)
3535
{
3636
server->credits += server->echo_credits + server->oplock_credits;
37+
if (server->credits > server->max_credits)
38+
server->credits = server->max_credits;
3739
server->oplock_credits = server->echo_credits = 0;
3840
switch (server->credits) {
3941
case 0:

fs/smb/client/smb2pdu.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,12 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
13051305
}
13061306

13071307
/* enough to enable echos and oplocks and one max size write */
1308-
req->hdr.CreditRequest = cpu_to_le16(130);
1308+
if (server->credits >= server->max_credits)
1309+
req->hdr.CreditRequest = cpu_to_le16(0);
1310+
else
1311+
req->hdr.CreditRequest = cpu_to_le16(
1312+
min_t(int, server->max_credits -
1313+
server->credits, 130));
13091314

13101315
/* only one of SMB2 signing flags may be set in SMB2 request */
13111316
if (server->sign)
@@ -1899,7 +1904,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
18991904
rqst.rq_nvec = 2;
19001905

19011906
/* Need 64 for max size write so ask for more in case not there yet */
1902-
req->hdr.CreditRequest = cpu_to_le16(64);
1907+
if (server->credits >= server->max_credits)
1908+
req->hdr.CreditRequest = cpu_to_le16(0);
1909+
else
1910+
req->hdr.CreditRequest = cpu_to_le16(
1911+
min_t(int, server->max_credits -
1912+
server->credits, 64));
19031913

19041914
rc = cifs_send_recv(xid, ses, server,
19051915
&rqst, &resp_buftype, flags, &rsp_iov);
@@ -4227,6 +4237,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
42274237
struct TCP_Server_Info *server;
42284238
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
42294239
unsigned int total_len;
4240+
int credit_request;
42304241

42314242
cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
42324243
__func__, rdata->offset, rdata->bytes);
@@ -4258,7 +4269,13 @@ smb2_async_readv(struct cifs_readdata *rdata)
42584269
if (rdata->credits.value > 0) {
42594270
shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
42604271
SMB2_MAX_BUFFER_SIZE));
4261-
shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4272+
credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
4273+
if (server->credits >= server->max_credits)
4274+
shdr->CreditRequest = cpu_to_le16(0);
4275+
else
4276+
shdr->CreditRequest = cpu_to_le16(
4277+
min_t(int, server->max_credits -
4278+
server->credits, credit_request));
42624279

42634280
rc = adjust_credits(server, &rdata->credits, rdata->bytes);
42644281
if (rc)
@@ -4468,6 +4485,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
44684485
unsigned int total_len;
44694486
struct cifs_io_parms _io_parms;
44704487
struct cifs_io_parms *io_parms = NULL;
4488+
int credit_request;
44714489

44724490
if (!wdata->server)
44734491
server = wdata->server = cifs_pick_channel(tcon->ses);
@@ -4572,7 +4590,13 @@ smb2_async_writev(struct cifs_writedata *wdata,
45724590
if (wdata->credits.value > 0) {
45734591
shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
45744592
SMB2_MAX_BUFFER_SIZE));
4575-
shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4593+
credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
4594+
if (server->credits >= server->max_credits)
4595+
shdr->CreditRequest = cpu_to_le16(0);
4596+
else
4597+
shdr->CreditRequest = cpu_to_le16(
4598+
min_t(int, server->max_credits -
4599+
server->credits, credit_request));
45764600

45774601
rc = adjust_credits(server, &wdata->credits, io_parms->length);
45784602
if (rc)

0 commit comments

Comments
 (0)