@@ -1265,7 +1265,7 @@ static void
12651265cifs_readv_callback (struct mid_q_entry * mid )
12661266{
12671267 struct cifs_io_subrequest * rdata = mid -> callback_data ;
1268- struct cifs_tcon * tcon = tlink_tcon (rdata -> cfile -> tlink );
1268+ struct cifs_tcon * tcon = tlink_tcon (rdata -> req -> cfile -> tlink );
12691269 struct TCP_Server_Info * server = tcon -> ses -> server ;
12701270 struct smb_rqst rqst = { .rq_iov = rdata -> iov ,
12711271 .rq_nvec = 2 ,
@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid)
13061306 rdata -> result = - EIO ;
13071307 }
13081308
1309- queue_work (cifsiod_wq , & rdata -> work );
1309+ if (rdata -> result == 0 || rdata -> result == - EAGAIN )
1310+ iov_iter_advance (& rdata -> subreq .io_iter , rdata -> got_bytes );
1311+ 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);
13101316 release_mid (mid );
13111317 add_credits (server , & credits , 0 );
13121318}
@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
13181324 int rc ;
13191325 READ_REQ * smb = NULL ;
13201326 int wct ;
1321- struct cifs_tcon * tcon = tlink_tcon (rdata -> cfile -> tlink );
1327+ struct cifs_tcon * tcon = tlink_tcon (rdata -> req -> cfile -> tlink );
13221328 struct smb_rqst rqst = { .rq_iov = rdata -> iov ,
13231329 .rq_nvec = 2 };
13241330
@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
13431349 smb -> hdr .PidHigh = cpu_to_le16 ((__u16 )(rdata -> pid >> 16 ));
13441350
13451351 smb -> AndXCommand = 0xFF ; /* none */
1346- smb -> Fid = rdata -> cfile -> fid .netfid ;
1352+ smb -> Fid = rdata -> req -> cfile -> fid .netfid ;
13471353 smb -> OffsetLow = cpu_to_le32 (rdata -> subreq .start & 0xFFFFFFFF );
13481354 if (wct == 12 )
13491355 smb -> OffsetHigh = cpu_to_le32 (rdata -> subreq .start >> 32 );
@@ -1613,15 +1619,16 @@ static void
16131619cifs_writev_callback (struct mid_q_entry * mid )
16141620{
16151621 struct cifs_io_subrequest * wdata = mid -> callback_data ;
1616- struct cifs_tcon * tcon = tlink_tcon (wdata -> cfile -> tlink );
1617- unsigned int written ;
1622+ struct cifs_tcon * tcon = tlink_tcon (wdata -> req -> cfile -> tlink );
16181623 WRITE_RSP * smb = (WRITE_RSP * )mid -> resp_buf ;
16191624 struct cifs_credits credits = { .value = 1 , .instance = 0 };
1625+ ssize_t result ;
1626+ size_t written ;
16201627
16211628 switch (mid -> mid_state ) {
16221629 case MID_RESPONSE_RECEIVED :
1623- wdata -> result = cifs_check_receive (mid , tcon -> ses -> server , 0 );
1624- if (wdata -> result != 0 )
1630+ result = cifs_check_receive (mid , tcon -> ses -> server , 0 );
1631+ if (result != 0 )
16251632 break ;
16261633
16271634 written = le16_to_cpu (smb -> CountHigh );
@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid)
16371644 written &= 0xFFFF ;
16381645
16391646 if (written < wdata -> subreq .len )
1640- wdata -> result = - ENOSPC ;
1647+ result = - ENOSPC ;
16411648 else
1642- wdata -> subreq . len = written ;
1649+ result = written ;
16431650 break ;
16441651 case MID_REQUEST_SUBMITTED :
16451652 case MID_RETRY_NEEDED :
1646- wdata -> result = - EAGAIN ;
1653+ result = - EAGAIN ;
16471654 break ;
16481655 default :
1649- wdata -> result = - EIO ;
1656+ result = - EIO ;
16501657 break ;
16511658 }
16521659
1653- queue_work (cifsiod_wq , & wdata -> work );
1660+ wdata -> credits .value = 0 ;
1661+ cifs_write_subrequest_terminated (wdata , result , true);
16541662 release_mid (mid );
16551663 add_credits (tcon -> ses -> server , & credits , 0 );
16561664}
16571665
16581666/* cifs_async_writev - send an async write, and set up mid to handle result */
1659- int
1667+ void
16601668cifs_async_writev (struct cifs_io_subrequest * wdata )
16611669{
16621670 int rc = - EACCES ;
16631671 WRITE_REQ * smb = NULL ;
16641672 int wct ;
1665- struct cifs_tcon * tcon = tlink_tcon (wdata -> cfile -> tlink );
1673+ struct cifs_tcon * tcon = tlink_tcon (wdata -> req -> cfile -> tlink );
16661674 struct kvec iov [2 ];
16671675 struct smb_rqst rqst = { };
16681676
@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
16721680 wct = 12 ;
16731681 if (wdata -> subreq .start >> 32 > 0 ) {
16741682 /* can not handle big offset for old srv */
1675- return - EIO ;
1683+ rc = - EIO ;
1684+ goto out ;
16761685 }
16771686 }
16781687
@@ -1684,7 +1693,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
16841693 smb -> hdr .PidHigh = cpu_to_le16 ((__u16 )(wdata -> pid >> 16 ));
16851694
16861695 smb -> AndXCommand = 0xFF ; /* none */
1687- smb -> Fid = wdata -> cfile -> fid .netfid ;
1696+ smb -> Fid = wdata -> req -> cfile -> fid .netfid ;
16881697 smb -> OffsetLow = cpu_to_le32 (wdata -> subreq .start & 0xFFFFFFFF );
16891698 if (wct == 14 )
16901699 smb -> OffsetHigh = cpu_to_le32 (wdata -> subreq .start >> 32 );
@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
17241733 iov [1 ].iov_len += 4 ; /* pad bigger by four bytes */
17251734 }
17261735
1727- cifs_get_writedata (wdata );
17281736 rc = cifs_call_async (tcon -> ses -> server , & rqst , NULL ,
17291737 cifs_writev_callback , NULL , wdata , 0 , NULL );
1730-
1738+ /* Can't touch wdata if rc == 0 */
17311739 if (rc == 0 )
17321740 cifs_stats_inc (& tcon -> stats .cifs_stats .num_writes );
1733- else
1734- cifs_put_writedata (wdata );
17351741
17361742async_writev_out :
17371743 cifs_small_buf_release (smb );
1738- return rc ;
1744+ out :
1745+ if (rc ) {
1746+ add_credits_and_wake_if (wdata -> server , & wdata -> credits , 0 );
1747+ cifs_write_subrequest_terminated (wdata , rc , false);
1748+ }
17391749}
17401750
17411751int
0 commit comments