@@ -1265,7 +1265,7 @@ static void
1265
1265
cifs_readv_callback (struct mid_q_entry * mid )
1266
1266
{
1267
1267
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 );
1269
1269
struct TCP_Server_Info * server = tcon -> ses -> server ;
1270
1270
struct smb_rqst rqst = { .rq_iov = rdata -> iov ,
1271
1271
.rq_nvec = 2 ,
@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid)
1306
1306
rdata -> result = - EIO ;
1307
1307
}
1308
1308
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);
1310
1316
release_mid (mid );
1311
1317
add_credits (server , & credits , 0 );
1312
1318
}
@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
1318
1324
int rc ;
1319
1325
READ_REQ * smb = NULL ;
1320
1326
int wct ;
1321
- struct cifs_tcon * tcon = tlink_tcon (rdata -> cfile -> tlink );
1327
+ struct cifs_tcon * tcon = tlink_tcon (rdata -> req -> cfile -> tlink );
1322
1328
struct smb_rqst rqst = { .rq_iov = rdata -> iov ,
1323
1329
.rq_nvec = 2 };
1324
1330
@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
1343
1349
smb -> hdr .PidHigh = cpu_to_le16 ((__u16 )(rdata -> pid >> 16 ));
1344
1350
1345
1351
smb -> AndXCommand = 0xFF ; /* none */
1346
- smb -> Fid = rdata -> cfile -> fid .netfid ;
1352
+ smb -> Fid = rdata -> req -> cfile -> fid .netfid ;
1347
1353
smb -> OffsetLow = cpu_to_le32 (rdata -> subreq .start & 0xFFFFFFFF );
1348
1354
if (wct == 12 )
1349
1355
smb -> OffsetHigh = cpu_to_le32 (rdata -> subreq .start >> 32 );
@@ -1613,15 +1619,16 @@ static void
1613
1619
cifs_writev_callback (struct mid_q_entry * mid )
1614
1620
{
1615
1621
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 );
1618
1623
WRITE_RSP * smb = (WRITE_RSP * )mid -> resp_buf ;
1619
1624
struct cifs_credits credits = { .value = 1 , .instance = 0 };
1625
+ ssize_t result ;
1626
+ size_t written ;
1620
1627
1621
1628
switch (mid -> mid_state ) {
1622
1629
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 )
1625
1632
break ;
1626
1633
1627
1634
written = le16_to_cpu (smb -> CountHigh );
@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid)
1637
1644
written &= 0xFFFF ;
1638
1645
1639
1646
if (written < wdata -> subreq .len )
1640
- wdata -> result = - ENOSPC ;
1647
+ result = - ENOSPC ;
1641
1648
else
1642
- wdata -> subreq . len = written ;
1649
+ result = written ;
1643
1650
break ;
1644
1651
case MID_REQUEST_SUBMITTED :
1645
1652
case MID_RETRY_NEEDED :
1646
- wdata -> result = - EAGAIN ;
1653
+ result = - EAGAIN ;
1647
1654
break ;
1648
1655
default :
1649
- wdata -> result = - EIO ;
1656
+ result = - EIO ;
1650
1657
break ;
1651
1658
}
1652
1659
1653
- queue_work (cifsiod_wq , & wdata -> work );
1660
+ wdata -> credits .value = 0 ;
1661
+ cifs_write_subrequest_terminated (wdata , result , true);
1654
1662
release_mid (mid );
1655
1663
add_credits (tcon -> ses -> server , & credits , 0 );
1656
1664
}
1657
1665
1658
1666
/* cifs_async_writev - send an async write, and set up mid to handle result */
1659
- int
1667
+ void
1660
1668
cifs_async_writev (struct cifs_io_subrequest * wdata )
1661
1669
{
1662
1670
int rc = - EACCES ;
1663
1671
WRITE_REQ * smb = NULL ;
1664
1672
int wct ;
1665
- struct cifs_tcon * tcon = tlink_tcon (wdata -> cfile -> tlink );
1673
+ struct cifs_tcon * tcon = tlink_tcon (wdata -> req -> cfile -> tlink );
1666
1674
struct kvec iov [2 ];
1667
1675
struct smb_rqst rqst = { };
1668
1676
@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
1672
1680
wct = 12 ;
1673
1681
if (wdata -> subreq .start >> 32 > 0 ) {
1674
1682
/* can not handle big offset for old srv */
1675
- return - EIO ;
1683
+ rc = - EIO ;
1684
+ goto out ;
1676
1685
}
1677
1686
}
1678
1687
@@ -1684,7 +1693,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
1684
1693
smb -> hdr .PidHigh = cpu_to_le16 ((__u16 )(wdata -> pid >> 16 ));
1685
1694
1686
1695
smb -> AndXCommand = 0xFF ; /* none */
1687
- smb -> Fid = wdata -> cfile -> fid .netfid ;
1696
+ smb -> Fid = wdata -> req -> cfile -> fid .netfid ;
1688
1697
smb -> OffsetLow = cpu_to_le32 (wdata -> subreq .start & 0xFFFFFFFF );
1689
1698
if (wct == 14 )
1690
1699
smb -> OffsetHigh = cpu_to_le32 (wdata -> subreq .start >> 32 );
@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
1724
1733
iov [1 ].iov_len += 4 ; /* pad bigger by four bytes */
1725
1734
}
1726
1735
1727
- cifs_get_writedata (wdata );
1728
1736
rc = cifs_call_async (tcon -> ses -> server , & rqst , NULL ,
1729
1737
cifs_writev_callback , NULL , wdata , 0 , NULL );
1730
-
1738
+ /* Can't touch wdata if rc == 0 */
1731
1739
if (rc == 0 )
1732
1740
cifs_stats_inc (& tcon -> stats .cifs_stats .num_writes );
1733
- else
1734
- cifs_put_writedata (wdata );
1735
1741
1736
1742
async_writev_out :
1737
1743
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
+ }
1739
1749
}
1740
1750
1741
1751
int
0 commit comments