@@ -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