34
34
#include <linux/slab.h>
35
35
#include <linux/sched.h>
36
36
#include <linux/uaccess.h>
37
+ #include <linux/uio.h>
37
38
#include <net/9p/9p.h>
38
39
#include <linux/parser.h>
39
40
#include <net/9p/client.h>
@@ -555,7 +556,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
555
556
*/
556
557
557
558
static int p9_check_zc_errors (struct p9_client * c , struct p9_req_t * req ,
558
- char * uidata , int in_hdrlen , int kern_buf )
559
+ struct iov_iter * uidata , int in_hdrlen )
559
560
{
560
561
int err ;
561
562
int ecode ;
@@ -591,16 +592,11 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
591
592
ename = & req -> rc -> sdata [req -> rc -> offset ];
592
593
if (len > inline_len ) {
593
594
/* We have error in external buffer */
594
- if (kern_buf ) {
595
- memcpy (ename + inline_len , uidata ,
596
- len - inline_len );
597
- } else {
598
- err = copy_from_user (ename + inline_len ,
599
- uidata , len - inline_len );
600
- if (err ) {
601
- err = - EFAULT ;
602
- goto out_err ;
603
- }
595
+ err = copy_from_iter (ename + inline_len ,
596
+ len - inline_len , uidata );
597
+ if (err != len - inline_len ) {
598
+ err = - EFAULT ;
599
+ goto out_err ;
604
600
}
605
601
}
606
602
ename = NULL ;
@@ -806,8 +802,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
806
802
* p9_client_zc_rpc - issue a request and wait for a response
807
803
* @c: client session
808
804
* @type: type of request
809
- * @uidata: user bffer that should be ued for zero copy read
810
- * @uodata: user buffer that shoud be user for zero copy write
805
+ * @uidata: destination for zero copy read
806
+ * @uodata: source for zero copy write
811
807
* @inlen: read buffer size
812
808
* @olen: write buffer size
813
809
* @hdrlen: reader header size, This is the size of response protocol data
@@ -816,9 +812,10 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
816
812
* Returns request structure (which client must free using p9_free_req)
817
813
*/
818
814
static struct p9_req_t * p9_client_zc_rpc (struct p9_client * c , int8_t type ,
819
- char * uidata , char * uodata ,
815
+ struct iov_iter * uidata ,
816
+ struct iov_iter * uodata ,
820
817
int inlen , int olen , int in_hdrlen ,
821
- int kern_buf , const char * fmt , ...)
818
+ const char * fmt , ...)
822
819
{
823
820
va_list ap ;
824
821
int sigpending , err ;
@@ -841,12 +838,8 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
841
838
} else
842
839
sigpending = 0 ;
843
840
844
- /* If we are called with KERNEL_DS force kern_buf */
845
- if (segment_eq (get_fs (), KERNEL_DS ))
846
- kern_buf = 1 ;
847
-
848
841
err = c -> trans_mod -> zc_request (c , req , uidata , uodata ,
849
- inlen , olen , in_hdrlen , kern_buf );
842
+ inlen , olen , in_hdrlen );
850
843
if (err < 0 ) {
851
844
if (err == - EIO )
852
845
c -> status = Disconnected ;
@@ -876,7 +869,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
876
869
if (err < 0 )
877
870
goto reterr ;
878
871
879
- err = p9_check_zc_errors (c , req , uidata , in_hdrlen , kern_buf );
872
+ err = p9_check_zc_errors (c , req , uidata , in_hdrlen );
880
873
trace_9p_client_res (c , type , req -> rc -> tag , err );
881
874
if (!err )
882
875
return req ;
@@ -1545,11 +1538,24 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1545
1538
u32 count )
1546
1539
{
1547
1540
char * dataptr ;
1548
- int kernel_buf = 0 ;
1549
1541
struct p9_req_t * req ;
1550
1542
struct p9_client * clnt ;
1551
1543
int err , rsize , non_zc = 0 ;
1552
-
1544
+ struct iov_iter to ;
1545
+ union {
1546
+ struct kvec kv ;
1547
+ struct iovec iov ;
1548
+ } v ;
1549
+
1550
+ if (data ) {
1551
+ v .kv .iov_base = data ;
1552
+ v .kv .iov_len = count ;
1553
+ iov_iter_kvec (& to , ITER_KVEC | READ , & v .kv , 1 , count );
1554
+ } else {
1555
+ v .iov .iov_base = udata ;
1556
+ v .iov .iov_len = count ;
1557
+ iov_iter_init (& to , READ , & v .iov , 1 , count );
1558
+ }
1553
1559
1554
1560
p9_debug (P9_DEBUG_9P , ">>> TREAD fid %d offset %llu %d\n" ,
1555
1561
fid -> fid , (unsigned long long ) offset , count );
@@ -1565,18 +1571,12 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1565
1571
1566
1572
/* Don't bother zerocopy for small IO (< 1024) */
1567
1573
if (clnt -> trans_mod -> zc_request && rsize > 1024 ) {
1568
- char * indata ;
1569
- if (data ) {
1570
- kernel_buf = 1 ;
1571
- indata = data ;
1572
- } else
1573
- indata = (__force char * )udata ;
1574
1574
/*
1575
1575
* response header len is 11
1576
1576
* PDU Header(7) + IO Size (4)
1577
1577
*/
1578
- req = p9_client_zc_rpc (clnt , P9_TREAD , indata , NULL , rsize , 0 ,
1579
- 11 , kernel_buf , "dqd" , fid -> fid ,
1578
+ req = p9_client_zc_rpc (clnt , P9_TREAD , & to , NULL , rsize , 0 ,
1579
+ 11 , "dqd" , fid -> fid ,
1580
1580
offset , rsize );
1581
1581
} else {
1582
1582
non_zc = 1 ;
@@ -1596,16 +1596,9 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1596
1596
1597
1597
p9_debug (P9_DEBUG_9P , "<<< RREAD count %d\n" , count );
1598
1598
1599
- if (non_zc ) {
1600
- if (data ) {
1601
- memmove (data , dataptr , count );
1602
- } else {
1603
- err = copy_to_user (udata , dataptr , count );
1604
- if (err ) {
1605
- err = - EFAULT ;
1606
- goto free_and_error ;
1607
- }
1608
- }
1599
+ if (non_zc && copy_to_iter (dataptr , count , & to ) != count ) {
1600
+ err = - EFAULT ;
1601
+ goto free_and_error ;
1609
1602
}
1610
1603
p9_free_req (clnt , req );
1611
1604
return count ;
@@ -1622,9 +1615,23 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1622
1615
u64 offset , u32 count )
1623
1616
{
1624
1617
int err , rsize ;
1625
- int kernel_buf = 0 ;
1626
1618
struct p9_client * clnt ;
1627
1619
struct p9_req_t * req ;
1620
+ struct iov_iter from ;
1621
+ union {
1622
+ struct kvec kv ;
1623
+ struct iovec iov ;
1624
+ } v ;
1625
+
1626
+ if (data ) {
1627
+ v .kv .iov_base = data ;
1628
+ v .kv .iov_len = count ;
1629
+ iov_iter_kvec (& from , ITER_KVEC | WRITE , & v .kv , 1 , count );
1630
+ } else {
1631
+ v .iov .iov_base = udata ;
1632
+ v .iov .iov_len = count ;
1633
+ iov_iter_init (& from , WRITE , & v .iov , 1 , count );
1634
+ }
1628
1635
1629
1636
p9_debug (P9_DEBUG_9P , ">>> TWRITE fid %d offset %llu count %d\n" ,
1630
1637
fid -> fid , (unsigned long long ) offset , count );
@@ -1640,22 +1647,12 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1640
1647
1641
1648
/* Don't bother zerocopy for small IO (< 1024) */
1642
1649
if (clnt -> trans_mod -> zc_request && rsize > 1024 ) {
1643
- char * odata ;
1644
- if (data ) {
1645
- kernel_buf = 1 ;
1646
- odata = data ;
1647
- } else
1648
- odata = (char * )udata ;
1649
- req = p9_client_zc_rpc (clnt , P9_TWRITE , NULL , odata , 0 , rsize ,
1650
- P9_ZC_HDR_SZ , kernel_buf , "dqd" ,
1650
+ req = p9_client_zc_rpc (clnt , P9_TWRITE , NULL , & from , 0 , rsize ,
1651
+ P9_ZC_HDR_SZ , "dqd" ,
1651
1652
fid -> fid , offset , rsize );
1652
1653
} else {
1653
- if (data )
1654
- req = p9_client_rpc (clnt , P9_TWRITE , "dqD" , fid -> fid ,
1655
- offset , rsize , data );
1656
- else
1657
- req = p9_client_rpc (clnt , P9_TWRITE , "dqU" , fid -> fid ,
1658
- offset , rsize , udata );
1654
+ req = p9_client_rpc (clnt , P9_TWRITE , "dqV" , fid -> fid ,
1655
+ offset , rsize , & from );
1659
1656
}
1660
1657
if (IS_ERR (req )) {
1661
1658
err = PTR_ERR (req );
@@ -2068,6 +2065,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2068
2065
struct p9_client * clnt ;
2069
2066
struct p9_req_t * req ;
2070
2067
char * dataptr ;
2068
+ struct kvec kv = {.iov_base = data , .iov_len = count };
2069
+ struct iov_iter to ;
2070
+
2071
+ iov_iter_kvec (& to , READ | ITER_KVEC , & kv , 1 , count );
2071
2072
2072
2073
p9_debug (P9_DEBUG_9P , ">>> TREADDIR fid %d offset %llu count %d\n" ,
2073
2074
fid -> fid , (unsigned long long ) offset , count );
@@ -2088,8 +2089,8 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2088
2089
* response header len is 11
2089
2090
* PDU Header(7) + IO Size (4)
2090
2091
*/
2091
- req = p9_client_zc_rpc (clnt , P9_TREADDIR , data , NULL , rsize , 0 ,
2092
- 11 , 1 , "dqd" , fid -> fid , offset , rsize );
2092
+ req = p9_client_zc_rpc (clnt , P9_TREADDIR , & to , NULL , rsize , 0 ,
2093
+ 11 , "dqd" , fid -> fid , offset , rsize );
2093
2094
} else {
2094
2095
non_zc = 1 ;
2095
2096
req = p9_client_rpc (clnt , P9_TREADDIR , "dqd" , fid -> fid ,
0 commit comments