aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 16:22:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 16:22:56 -0400
commitfa927894bbb4a4c7669c72bad1924991022fda38 (patch)
tree93560f1a096973235fe9ff50c436f5239c1c499a /net
parentc841e12add6926d64aa608687893465330b5a03e (diff)
parent8436318205b9f29e45db88850ec60e326327e241 (diff)
Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs update from Al Viro: "Now that net-next went in... Here's the next big chunk - killing ->aio_read() and ->aio_write(). There'll be one more pile today (direct_IO changes and generic_write_checks() cleanups/fixes), but I'd prefer to keep that one separate" * 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (37 commits) ->aio_read and ->aio_write removed pcm: another weird API abuse infinibad: weird APIs switched to ->write_iter() kill do_sync_read/do_sync_write fuse: use iov_iter_get_pages() for non-splice path fuse: switch to ->read_iter/->write_iter switch drivers/char/mem.c to ->read_iter/->write_iter make new_sync_{read,write}() static coredump: accept any write method switch /dev/loop to vfs_iter_write() serial2002: switch to __vfs_read/__vfs_write ashmem: use __vfs_read() export __vfs_read() autofs: switch to __vfs_write() new helper: __vfs_write() switch hugetlbfs to ->read_iter() coda: switch to ->read_iter/->write_iter ncpfs: switch to ->read_iter/->write_iter net/9p: remove (now-)unused helpers p9_client_attach(): set fid->uid correctly ...
Diffstat (limited to 'net')
-rw-r--r--net/9p/client.c262
-rw-r--r--net/9p/protocol.c24
-rw-r--r--net/9p/trans_common.c42
-rw-r--r--net/9p/trans_common.h2
-rw-r--r--net/9p/trans_virtio.c137
-rw-r--r--net/socket.c2
6 files changed, 211 insertions, 258 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index e86a9bea1d16..6f4c4c88db84 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <linux/uio.h>
37#include <net/9p/9p.h> 38#include <net/9p/9p.h>
38#include <linux/parser.h> 39#include <linux/parser.h>
39#include <net/9p/client.h> 40#include <net/9p/client.h>
@@ -555,7 +556,7 @@ out_err:
555 */ 556 */
556 557
557static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, 558static 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 int err; 561 int err;
561 int ecode; 562 int ecode;
@@ -591,16 +592,11 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
591 ename = &req->rc->sdata[req->rc->offset]; 592 ename = &req->rc->sdata[req->rc->offset];
592 if (len > inline_len) { 593 if (len > inline_len) {
593 /* We have error in external buffer */ 594 /* We have error in external buffer */
594 if (kern_buf) { 595 err = copy_from_iter(ename + inline_len,
595 memcpy(ename + inline_len, uidata, 596 len - inline_len, uidata);
596 len - inline_len); 597 if (err != len - inline_len) {
597 } else { 598 err = -EFAULT;
598 err = copy_from_user(ename + inline_len, 599 goto out_err;
599 uidata, len - inline_len);
600 if (err) {
601 err = -EFAULT;
602 goto out_err;
603 }
604 } 600 }
605 } 601 }
606 ename = NULL; 602 ename = NULL;
@@ -806,8 +802,8 @@ reterr:
806 * p9_client_zc_rpc - issue a request and wait for a response 802 * p9_client_zc_rpc - issue a request and wait for a response
807 * @c: client session 803 * @c: client session
808 * @type: type of request 804 * @type: type of request
809 * @uidata: user bffer that should be ued for zero copy read 805 * @uidata: destination for zero copy read
810 * @uodata: user buffer that shoud be user for zero copy write 806 * @uodata: source for zero copy write
811 * @inlen: read buffer size 807 * @inlen: read buffer size
812 * @olen: write buffer size 808 * @olen: write buffer size
813 * @hdrlen: reader header size, This is the size of response protocol data 809 * @hdrlen: reader header size, This is the size of response protocol data
@@ -816,9 +812,10 @@ reterr:
816 * Returns request structure (which client must free using p9_free_req) 812 * Returns request structure (which client must free using p9_free_req)
817 */ 813 */
818static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, 814static 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 int inlen, int olen, int in_hdrlen, 817 int inlen, int olen, int in_hdrlen,
821 int kern_buf, const char *fmt, ...) 818 const char *fmt, ...)
822{ 819{
823 va_list ap; 820 va_list ap;
824 int sigpending, err; 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 } else 838 } else
842 sigpending = 0; 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 err = c->trans_mod->zc_request(c, req, uidata, uodata, 841 err = c->trans_mod->zc_request(c, req, uidata, uodata,
849 inlen, olen, in_hdrlen, kern_buf); 842 inlen, olen, in_hdrlen);
850 if (err < 0) { 843 if (err < 0) {
851 if (err == -EIO) 844 if (err == -EIO)
852 c->status = Disconnected; 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 if (err < 0) 869 if (err < 0)
877 goto reterr; 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 trace_9p_client_res(c, type, req->rc->tag, err); 873 trace_9p_client_res(c, type, req->rc->tag, err);
881 if (!err) 874 if (!err)
882 return req; 875 return req;
@@ -1123,6 +1116,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1123 fid = NULL; 1116 fid = NULL;
1124 goto error; 1117 goto error;
1125 } 1118 }
1119 fid->uid = n_uname;
1126 1120
1127 req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid, 1121 req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
1128 afid ? afid->fid : P9_NOFID, uname, aname, n_uname); 1122 afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
@@ -1541,142 +1535,128 @@ error:
1541EXPORT_SYMBOL(p9_client_unlinkat); 1535EXPORT_SYMBOL(p9_client_unlinkat);
1542 1536
1543int 1537int
1544p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, 1538p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
1545 u32 count)
1546{ 1539{
1547 char *dataptr; 1540 struct p9_client *clnt = fid->clnt;
1548 int kernel_buf = 0;
1549 struct p9_req_t *req; 1541 struct p9_req_t *req;
1550 struct p9_client *clnt; 1542 int total = 0;
1551 int err, rsize, non_zc = 0;
1552
1553 1543
1554 p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", 1544 p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
1555 fid->fid, (unsigned long long) offset, count); 1545 fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
1556 err = 0; 1546
1557 clnt = fid->clnt; 1547 while (iov_iter_count(to)) {
1558 1548 int count = iov_iter_count(to);
1559 rsize = fid->iounit; 1549 int rsize, non_zc = 0;
1560 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) 1550 char *dataptr;
1561 rsize = clnt->msize - P9_IOHDRSZ; 1551
1562 1552 rsize = fid->iounit;
1563 if (count < rsize) 1553 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1564 rsize = count; 1554 rsize = clnt->msize - P9_IOHDRSZ;
1565 1555
1566 /* Don't bother zerocopy for small IO (< 1024) */ 1556 if (count < rsize)
1567 if (clnt->trans_mod->zc_request && rsize > 1024) { 1557 rsize = count;
1568 char *indata; 1558
1569 if (data) { 1559 /* Don't bother zerocopy for small IO (< 1024) */
1570 kernel_buf = 1; 1560 if (clnt->trans_mod->zc_request && rsize > 1024) {
1571 indata = data; 1561 /*
1572 } else 1562 * response header len is 11
1573 indata = (__force char *)udata; 1563 * PDU Header(7) + IO Size (4)
1574 /* 1564 */
1575 * response header len is 11 1565 req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
1576 * PDU Header(7) + IO Size (4) 1566 0, 11, "dqd", fid->fid,
1577 */ 1567 offset, rsize);
1578 req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0, 1568 } else {
1579 11, kernel_buf, "dqd", fid->fid, 1569 non_zc = 1;
1580 offset, rsize); 1570 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1581 } else { 1571 rsize);
1582 non_zc = 1; 1572 }
1583 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, 1573 if (IS_ERR(req)) {
1584 rsize); 1574 *err = PTR_ERR(req);
1585 } 1575 break;
1586 if (IS_ERR(req)) { 1576 }
1587 err = PTR_ERR(req);
1588 goto error;
1589 }
1590 1577
1591 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1578 *err = p9pdu_readf(req->rc, clnt->proto_version,
1592 if (err) { 1579 "D", &count, &dataptr);
1593 trace_9p_protocol_dump(clnt, req->rc); 1580 if (*err) {
1594 goto free_and_error; 1581 trace_9p_protocol_dump(clnt, req->rc);
1595 } 1582 p9_free_req(clnt, req);
1583 break;
1584 }
1596 1585
1597 p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1586 p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1587 if (!count) {
1588 p9_free_req(clnt, req);
1589 break;
1590 }
1598 1591
1599 if (non_zc) { 1592 if (non_zc) {
1600 if (data) { 1593 int n = copy_to_iter(dataptr, count, to);
1601 memmove(data, dataptr, count); 1594 total += n;
1602 } else { 1595 offset += n;
1603 err = copy_to_user(udata, dataptr, count); 1596 if (n != count) {
1604 if (err) { 1597 *err = -EFAULT;
1605 err = -EFAULT; 1598 p9_free_req(clnt, req);
1606 goto free_and_error; 1599 break;
1607 } 1600 }
1601 } else {
1602 iov_iter_advance(to, count);
1603 total += count;
1604 offset += count;
1608 } 1605 }
1606 p9_free_req(clnt, req);
1609 } 1607 }
1610 p9_free_req(clnt, req); 1608 return total;
1611 return count;
1612
1613free_and_error:
1614 p9_free_req(clnt, req);
1615error:
1616 return err;
1617} 1609}
1618EXPORT_SYMBOL(p9_client_read); 1610EXPORT_SYMBOL(p9_client_read);
1619 1611
1620int 1612int
1621p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, 1613p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
1622 u64 offset, u32 count)
1623{ 1614{
1624 int err, rsize; 1615 struct p9_client *clnt = fid->clnt;
1625 int kernel_buf = 0;
1626 struct p9_client *clnt;
1627 struct p9_req_t *req; 1616 struct p9_req_t *req;
1617 int total = 0;
1618
1619 p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n",
1620 fid->fid, (unsigned long long) offset,
1621 iov_iter_count(from));
1622
1623 while (iov_iter_count(from)) {
1624 int count = iov_iter_count(from);
1625 int rsize = fid->iounit;
1626 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1627 rsize = clnt->msize - P9_IOHDRSZ;
1628
1629 if (count < rsize)
1630 rsize = count;
1631
1632 /* Don't bother zerocopy for small IO (< 1024) */
1633 if (clnt->trans_mod->zc_request && rsize > 1024) {
1634 req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, from, 0,
1635 rsize, P9_ZC_HDR_SZ, "dqd",
1636 fid->fid, offset, rsize);
1637 } else {
1638 req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid,
1639 offset, rsize, from);
1640 }
1641 if (IS_ERR(req)) {
1642 *err = PTR_ERR(req);
1643 break;
1644 }
1628 1645
1629 p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n", 1646 *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1630 fid->fid, (unsigned long long) offset, count); 1647 if (*err) {
1631 err = 0; 1648 trace_9p_protocol_dump(clnt, req->rc);
1632 clnt = fid->clnt; 1649 p9_free_req(clnt, req);
1633 1650 }
1634 rsize = fid->iounit;
1635 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1636 rsize = clnt->msize - P9_IOHDRSZ;
1637 1651
1638 if (count < rsize) 1652 p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
1639 rsize = count;
1640 1653
1641 /* Don't bother zerocopy for small IO (< 1024) */ 1654 p9_free_req(clnt, req);
1642 if (clnt->trans_mod->zc_request && rsize > 1024) { 1655 iov_iter_advance(from, count);
1643 char *odata; 1656 total += count;
1644 if (data) { 1657 offset += count;
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",
1651 fid->fid, offset, rsize);
1652 } 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);
1659 }
1660 if (IS_ERR(req)) {
1661 err = PTR_ERR(req);
1662 goto error;
1663 }
1664
1665 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1666 if (err) {
1667 trace_9p_protocol_dump(clnt, req->rc);
1668 goto free_and_error;
1669 } 1658 }
1670 1659 return total;
1671 p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
1672
1673 p9_free_req(clnt, req);
1674 return count;
1675
1676free_and_error:
1677 p9_free_req(clnt, req);
1678error:
1679 return err;
1680} 1660}
1681EXPORT_SYMBOL(p9_client_write); 1661EXPORT_SYMBOL(p9_client_write);
1682 1662
@@ -2068,6 +2048,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2068 struct p9_client *clnt; 2048 struct p9_client *clnt;
2069 struct p9_req_t *req; 2049 struct p9_req_t *req;
2070 char *dataptr; 2050 char *dataptr;
2051 struct kvec kv = {.iov_base = data, .iov_len = count};
2052 struct iov_iter to;
2053
2054 iov_iter_kvec(&to, READ | ITER_KVEC, &kv, 1, count);
2071 2055
2072 p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", 2056 p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
2073 fid->fid, (unsigned long long) offset, count); 2057 fid->fid, (unsigned long long) offset, count);
@@ -2088,8 +2072,8 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2088 * response header len is 11 2072 * response header len is 11
2089 * PDU Header(7) + IO Size (4) 2073 * PDU Header(7) + IO Size (4)
2090 */ 2074 */
2091 req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0, 2075 req = p9_client_zc_rpc(clnt, P9_TREADDIR, &to, NULL, rsize, 0,
2092 11, 1, "dqd", fid->fid, offset, rsize); 2076 11, "dqd", fid->fid, offset, rsize);
2093 } else { 2077 } else {
2094 non_zc = 1; 2078 non_zc = 1;
2095 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, 2079 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index ab9127ec5b7a..e9d0f0c1a048 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -33,6 +33,7 @@
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/stddef.h> 34#include <linux/stddef.h>
35#include <linux/types.h> 35#include <linux/types.h>
36#include <linux/uio.h>
36#include <net/9p/9p.h> 37#include <net/9p/9p.h>
37#include <net/9p/client.h> 38#include <net/9p/client.h>
38#include "protocol.h" 39#include "protocol.h"
@@ -69,10 +70,11 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
69} 70}
70 71
71static size_t 72static size_t
72pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) 73pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
73{ 74{
74 size_t len = min(pdu->capacity - pdu->size, size); 75 size_t len = min(pdu->capacity - pdu->size, size);
75 if (copy_from_user(&pdu->sdata[pdu->size], udata, len)) 76 struct iov_iter i = *from;
77 if (copy_from_iter(&pdu->sdata[pdu->size], len, &i) != len)
76 len = 0; 78 len = 0;
77 79
78 pdu->size += len; 80 pdu->size += len;
@@ -437,23 +439,13 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
437 stbuf->extension, stbuf->n_uid, 439 stbuf->extension, stbuf->n_uid,
438 stbuf->n_gid, stbuf->n_muid); 440 stbuf->n_gid, stbuf->n_muid);
439 } break; 441 } break;
440 case 'D':{ 442 case 'V':{
441 uint32_t count = va_arg(ap, uint32_t);
442 const void *data = va_arg(ap, const void *);
443
444 errcode = p9pdu_writef(pdu, proto_version, "d",
445 count);
446 if (!errcode && pdu_write(pdu, data, count))
447 errcode = -EFAULT;
448 }
449 break;
450 case 'U':{
451 int32_t count = va_arg(ap, int32_t); 443 int32_t count = va_arg(ap, int32_t);
452 const char __user *udata = 444 struct iov_iter *from =
453 va_arg(ap, const void __user *); 445 va_arg(ap, struct iov_iter *);
454 errcode = p9pdu_writef(pdu, proto_version, "d", 446 errcode = p9pdu_writef(pdu, proto_version, "d",
455 count); 447 count);
456 if (!errcode && pdu_write_u(pdu, udata, count)) 448 if (!errcode && pdu_write_u(pdu, from, count))
457 errcode = -EFAULT; 449 errcode = -EFAULT;
458 } 450 }
459 break; 451 break;
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c
index 2ee3879161b1..38aa6345bdfa 100644
--- a/net/9p/trans_common.c
+++ b/net/9p/trans_common.c
@@ -12,12 +12,8 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/slab.h> 15#include <linux/mm.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <net/9p/9p.h>
18#include <net/9p/client.h>
19#include <linux/scatterlist.h>
20#include "trans_common.h"
21 17
22/** 18/**
23 * p9_release_req_pages - Release pages after the transaction. 19 * p9_release_req_pages - Release pages after the transaction.
@@ -31,39 +27,3 @@ void p9_release_pages(struct page **pages, int nr_pages)
31 put_page(pages[i]); 27 put_page(pages[i]);
32} 28}
33EXPORT_SYMBOL(p9_release_pages); 29EXPORT_SYMBOL(p9_release_pages);
34
35/**
36 * p9_nr_pages - Return number of pages needed to accommodate the payload.
37 */
38int p9_nr_pages(char *data, int len)
39{
40 unsigned long start_page, end_page;
41 start_page = (unsigned long)data >> PAGE_SHIFT;
42 end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
43 return end_page - start_page;
44}
45EXPORT_SYMBOL(p9_nr_pages);
46
47/**
48 * payload_gup - Translates user buffer into kernel pages and
49 * pins them either for read/write through get_user_pages_fast().
50 * @req: Request to be sent to server.
51 * @pdata_off: data offset into the first page after translation (gup).
52 * @pdata_len: Total length of the IO. gup may not return requested # of pages.
53 * @nr_pages: number of pages to accommodate the payload
54 * @rw: Indicates if the pages are for read or write.
55 */
56
57int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
58{
59 int nr_mapped_pages;
60
61 nr_mapped_pages = get_user_pages_fast((unsigned long)data,
62 *nr_pages, write, pages);
63 if (nr_mapped_pages <= 0)
64 return nr_mapped_pages;
65
66 *nr_pages = nr_mapped_pages;
67 return 0;
68}
69EXPORT_SYMBOL(p9_payload_gup);
diff --git a/net/9p/trans_common.h b/net/9p/trans_common.h
index 173bb550a9eb..c43babb3f635 100644
--- a/net/9p/trans_common.h
+++ b/net/9p/trans_common.h
@@ -13,5 +13,3 @@
13 */ 13 */
14 14
15void p9_release_pages(struct page **, int); 15void p9_release_pages(struct page **, int);
16int p9_payload_gup(char *, int *, struct page **, int);
17int p9_nr_pages(char *, int);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 36a1a739ad68..e62bcbbabb5e 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -217,15 +217,15 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
217 * @start: which segment of the sg_list to start at 217 * @start: which segment of the sg_list to start at
218 * @pdata: a list of pages to add into sg. 218 * @pdata: a list of pages to add into sg.
219 * @nr_pages: number of pages to pack into the scatter/gather list 219 * @nr_pages: number of pages to pack into the scatter/gather list
220 * @data: data to pack into scatter/gather list 220 * @offs: amount of data in the beginning of first page _not_ to pack
221 * @count: amount of data to pack into the scatter/gather list 221 * @count: amount of data to pack into the scatter/gather list
222 */ 222 */
223static int 223static int
224pack_sg_list_p(struct scatterlist *sg, int start, int limit, 224pack_sg_list_p(struct scatterlist *sg, int start, int limit,
225 struct page **pdata, int nr_pages, char *data, int count) 225 struct page **pdata, int nr_pages, size_t offs, int count)
226{ 226{
227 int i = 0, s; 227 int i = 0, s;
228 int data_off; 228 int data_off = offs;
229 int index = start; 229 int index = start;
230 230
231 BUG_ON(nr_pages > (limit - start)); 231 BUG_ON(nr_pages > (limit - start));
@@ -233,16 +233,14 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit,
233 * if the first page doesn't start at 233 * if the first page doesn't start at
234 * page boundary find the offset 234 * page boundary find the offset
235 */ 235 */
236 data_off = offset_in_page(data);
237 while (nr_pages) { 236 while (nr_pages) {
238 s = rest_of_page(data); 237 s = PAGE_SIZE - data_off;
239 if (s > count) 238 if (s > count)
240 s = count; 239 s = count;
241 /* Make sure we don't terminate early. */ 240 /* Make sure we don't terminate early. */
242 sg_unmark_end(&sg[index]); 241 sg_unmark_end(&sg[index]);
243 sg_set_page(&sg[index++], pdata[i++], s, data_off); 242 sg_set_page(&sg[index++], pdata[i++], s, data_off);
244 data_off = 0; 243 data_off = 0;
245 data += s;
246 count -= s; 244 count -= s;
247 nr_pages--; 245 nr_pages--;
248 } 246 }
@@ -314,11 +312,20 @@ req_retry:
314} 312}
315 313
316static int p9_get_mapped_pages(struct virtio_chan *chan, 314static int p9_get_mapped_pages(struct virtio_chan *chan,
317 struct page **pages, char *data, 315 struct page ***pages,
318 int nr_pages, int write, int kern_buf) 316 struct iov_iter *data,
317 int count,
318 size_t *offs,
319 int *need_drop)
319{ 320{
321 int nr_pages;
320 int err; 322 int err;
321 if (!kern_buf) { 323
324 if (!iov_iter_count(data))
325 return 0;
326
327 if (!(data->type & ITER_KVEC)) {
328 int n;
322 /* 329 /*
323 * We allow only p9_max_pages pinned. We wait for the 330 * We allow only p9_max_pages pinned. We wait for the
324 * Other zc request to finish here 331 * Other zc request to finish here
@@ -329,26 +336,49 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
329 if (err == -ERESTARTSYS) 336 if (err == -ERESTARTSYS)
330 return err; 337 return err;
331 } 338 }
332 err = p9_payload_gup(data, &nr_pages, pages, write); 339 n = iov_iter_get_pages_alloc(data, pages, count, offs);
333 if (err < 0) 340 if (n < 0)
334 return err; 341 return n;
342 *need_drop = 1;
343 nr_pages = DIV_ROUND_UP(n + *offs, PAGE_SIZE);
335 atomic_add(nr_pages, &vp_pinned); 344 atomic_add(nr_pages, &vp_pinned);
345 return n;
336 } else { 346 } else {
337 /* kernel buffer, no need to pin pages */ 347 /* kernel buffer, no need to pin pages */
338 int s, index = 0; 348 int index;
339 int count = nr_pages; 349 size_t len;
340 while (nr_pages) { 350 void *p;
341 s = rest_of_page(data); 351
342 if (is_vmalloc_addr(data)) 352 /* we'd already checked that it's non-empty */
343 pages[index++] = vmalloc_to_page(data); 353 while (1) {
354 len = iov_iter_single_seg_count(data);
355 if (likely(len)) {
356 p = data->kvec->iov_base + data->iov_offset;
357 break;
358 }
359 iov_iter_advance(data, 0);
360 }
361 if (len > count)
362 len = count;
363
364 nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) -
365 (unsigned long)p / PAGE_SIZE;
366
367 *pages = kmalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
368 if (!*pages)
369 return -ENOMEM;
370
371 *need_drop = 0;
372 p -= (*offs = (unsigned long)p % PAGE_SIZE);
373 for (index = 0; index < nr_pages; index++) {
374 if (is_vmalloc_addr(p))
375 (*pages)[index] = vmalloc_to_page(p);
344 else 376 else
345 pages[index++] = kmap_to_page(data); 377 (*pages)[index] = kmap_to_page(p);
346 data += s; 378 p += PAGE_SIZE;
347 nr_pages--;
348 } 379 }
349 nr_pages = count; 380 return len;
350 } 381 }
351 return nr_pages;
352} 382}
353 383
354/** 384/**
@@ -364,8 +394,8 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
364 */ 394 */
365static int 395static int
366p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, 396p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
367 char *uidata, char *uodata, int inlen, 397 struct iov_iter *uidata, struct iov_iter *uodata,
368 int outlen, int in_hdr_len, int kern_buf) 398 int inlen, int outlen, int in_hdr_len)
369{ 399{
370 int in, out, err, out_sgs, in_sgs; 400 int in, out, err, out_sgs, in_sgs;
371 unsigned long flags; 401 unsigned long flags;
@@ -373,41 +403,32 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
373 struct page **in_pages = NULL, **out_pages = NULL; 403 struct page **in_pages = NULL, **out_pages = NULL;
374 struct virtio_chan *chan = client->trans; 404 struct virtio_chan *chan = client->trans;
375 struct scatterlist *sgs[4]; 405 struct scatterlist *sgs[4];
406 size_t offs;
407 int need_drop = 0;
376 408
377 p9_debug(P9_DEBUG_TRANS, "virtio request\n"); 409 p9_debug(P9_DEBUG_TRANS, "virtio request\n");
378 410
379 if (uodata) { 411 if (uodata) {
380 out_nr_pages = p9_nr_pages(uodata, outlen); 412 int n = p9_get_mapped_pages(chan, &out_pages, uodata,
381 out_pages = kmalloc(sizeof(struct page *) * out_nr_pages, 413 outlen, &offs, &need_drop);
382 GFP_NOFS); 414 if (n < 0)
383 if (!out_pages) { 415 return n;
384 err = -ENOMEM; 416 out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
385 goto err_out; 417 if (n != outlen) {
386 } 418 __le32 v = cpu_to_le32(n);
387 out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata, 419 memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
388 out_nr_pages, 0, kern_buf); 420 outlen = n;
389 if (out_nr_pages < 0) {
390 err = out_nr_pages;
391 kfree(out_pages);
392 out_pages = NULL;
393 goto err_out;
394 } 421 }
395 } 422 } else if (uidata) {
396 if (uidata) { 423 int n = p9_get_mapped_pages(chan, &in_pages, uidata,
397 in_nr_pages = p9_nr_pages(uidata, inlen); 424 inlen, &offs, &need_drop);
398 in_pages = kmalloc(sizeof(struct page *) * in_nr_pages, 425 if (n < 0)
399 GFP_NOFS); 426 return n;
400 if (!in_pages) { 427 in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
401 err = -ENOMEM; 428 if (n != inlen) {
402 goto err_out; 429 __le32 v = cpu_to_le32(n);
403 } 430 memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
404 in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata, 431 inlen = n;
405 in_nr_pages, 1, kern_buf);
406 if (in_nr_pages < 0) {
407 err = in_nr_pages;
408 kfree(in_pages);
409 in_pages = NULL;
410 goto err_out;
411 } 432 }
412 } 433 }
413 req->status = REQ_STATUS_SENT; 434 req->status = REQ_STATUS_SENT;
@@ -426,7 +447,7 @@ req_retry_pinned:
426 if (out_pages) { 447 if (out_pages) {
427 sgs[out_sgs++] = chan->sg + out; 448 sgs[out_sgs++] = chan->sg + out;
428 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, 449 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
429 out_pages, out_nr_pages, uodata, outlen); 450 out_pages, out_nr_pages, offs, outlen);
430 } 451 }
431 452
432 /* 453 /*
@@ -444,7 +465,7 @@ req_retry_pinned:
444 if (in_pages) { 465 if (in_pages) {
445 sgs[out_sgs + in_sgs++] = chan->sg + out + in; 466 sgs[out_sgs + in_sgs++] = chan->sg + out + in;
446 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM, 467 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
447 in_pages, in_nr_pages, uidata, inlen); 468 in_pages, in_nr_pages, offs, inlen);
448 } 469 }
449 470
450 BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs)); 471 BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
@@ -478,7 +499,7 @@ req_retry_pinned:
478 * Non kernel buffers are pinned, unpin them 499 * Non kernel buffers are pinned, unpin them
479 */ 500 */
480err_out: 501err_out:
481 if (!kern_buf) { 502 if (need_drop) {
482 if (in_pages) { 503 if (in_pages) {
483 p9_release_pages(in_pages, in_nr_pages); 504 p9_release_pages(in_pages, in_nr_pages);
484 atomic_sub(in_nr_pages, &vp_pinned); 505 atomic_sub(in_nr_pages, &vp_pinned);
diff --git a/net/socket.c b/net/socket.c
index 5b0126234606..3e33959f3ce5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -140,8 +140,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
140static const struct file_operations socket_file_ops = { 140static const struct file_operations socket_file_ops = {
141 .owner = THIS_MODULE, 141 .owner = THIS_MODULE,
142 .llseek = no_llseek, 142 .llseek = no_llseek,
143 .read = new_sync_read,
144 .write = new_sync_write,
145 .read_iter = sock_read_iter, 143 .read_iter = sock_read_iter,
146 .write_iter = sock_write_iter, 144 .write_iter = sock_write_iter,
147 .poll = sock_poll, 145 .poll = sock_poll,