diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-01 23:42:28 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:28:27 -0400 |
commit | e1200fe68f20759f359698f8a8dc81d06d1265f5 (patch) | |
tree | 2f6a596be0d8d2aa759687be4c0e9f4e0ecc1723 /net | |
parent | 9565a5445240cd441f2c670aa7260ee8eb5dff79 (diff) |
9p: switch p9_client_read() to passing struct iov_iter *
... and make it loop
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 124 |
1 files changed, 61 insertions, 63 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index aa38cfeb8615..18583bb89db6 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1534,79 +1534,77 @@ error: | |||
1534 | EXPORT_SYMBOL(p9_client_unlinkat); | 1534 | EXPORT_SYMBOL(p9_client_unlinkat); |
1535 | 1535 | ||
1536 | int | 1536 | int |
1537 | p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | 1537 | p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) |
1538 | u32 count) | ||
1539 | { | 1538 | { |
1540 | char *dataptr; | 1539 | struct p9_client *clnt = fid->clnt; |
1541 | struct p9_req_t *req; | 1540 | struct p9_req_t *req; |
1542 | struct p9_client *clnt; | 1541 | int total = 0; |
1543 | int err, rsize, non_zc = 0; | ||
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 | } | ||
1559 | 1542 | ||
1560 | p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", | 1543 | p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", |
1561 | fid->fid, (unsigned long long) offset, count); | 1544 | fid->fid, (unsigned long long) offset, (int)iov_iter_count(to)); |
1562 | err = 0; | 1545 | |
1563 | clnt = fid->clnt; | 1546 | while (iov_iter_count(to)) { |
1564 | 1547 | int count = iov_iter_count(to); | |
1565 | rsize = fid->iounit; | 1548 | int rsize, non_zc = 0; |
1566 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | 1549 | char *dataptr; |
1567 | rsize = clnt->msize - P9_IOHDRSZ; | 1550 | |
1551 | rsize = fid->iounit; | ||
1552 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
1553 | rsize = clnt->msize - P9_IOHDRSZ; | ||
1568 | 1554 | ||
1569 | if (count < rsize) | 1555 | if (count < rsize) |
1570 | rsize = count; | 1556 | rsize = count; |
1571 | 1557 | ||
1572 | /* Don't bother zerocopy for small IO (< 1024) */ | 1558 | /* Don't bother zerocopy for small IO (< 1024) */ |
1573 | if (clnt->trans_mod->zc_request && rsize > 1024) { | 1559 | if (clnt->trans_mod->zc_request && rsize > 1024) { |
1574 | /* | 1560 | /* |
1575 | * response header len is 11 | 1561 | * response header len is 11 |
1576 | * PDU Header(7) + IO Size (4) | 1562 | * PDU Header(7) + IO Size (4) |
1577 | */ | 1563 | */ |
1578 | req = p9_client_zc_rpc(clnt, P9_TREAD, &to, NULL, rsize, 0, | 1564 | req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize, |
1579 | 11, "dqd", fid->fid, | 1565 | 0, 11, "dqd", fid->fid, |
1580 | offset, rsize); | 1566 | offset, rsize); |
1581 | } else { | 1567 | } else { |
1582 | non_zc = 1; | 1568 | non_zc = 1; |
1583 | req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, | 1569 | req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, |
1584 | rsize); | 1570 | rsize); |
1585 | } | 1571 | } |
1586 | if (IS_ERR(req)) { | 1572 | if (IS_ERR(req)) { |
1587 | err = PTR_ERR(req); | 1573 | *err = PTR_ERR(req); |
1588 | goto error; | 1574 | break; |
1589 | } | 1575 | } |
1590 | 1576 | ||
1591 | err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); | 1577 | *err = p9pdu_readf(req->rc, clnt->proto_version, |
1592 | if (err) { | 1578 | "D", &count, &dataptr); |
1593 | trace_9p_protocol_dump(clnt, req->rc); | 1579 | if (*err) { |
1594 | goto free_and_error; | 1580 | trace_9p_protocol_dump(clnt, req->rc); |
1595 | } | 1581 | p9_free_req(clnt, req); |
1582 | break; | ||
1583 | } | ||
1596 | 1584 | ||
1597 | p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); | 1585 | p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); |
1586 | if (!count) { | ||
1587 | p9_free_req(clnt, req); | ||
1588 | break; | ||
1589 | } | ||
1598 | 1590 | ||
1599 | if (non_zc && copy_to_iter(dataptr, count, &to) != count) { | 1591 | if (non_zc) { |
1600 | err = -EFAULT; | 1592 | int n = copy_to_iter(dataptr, count, to); |
1601 | goto free_and_error; | 1593 | total += n; |
1594 | offset += n; | ||
1595 | if (n != count) { | ||
1596 | *err = -EFAULT; | ||
1597 | p9_free_req(clnt, req); | ||
1598 | break; | ||
1599 | } | ||
1600 | } else { | ||
1601 | iov_iter_advance(to, count); | ||
1602 | total += count; | ||
1603 | offset += count; | ||
1604 | } | ||
1605 | p9_free_req(clnt, req); | ||
1602 | } | 1606 | } |
1603 | p9_free_req(clnt, req); | 1607 | return total; |
1604 | return count; | ||
1605 | |||
1606 | free_and_error: | ||
1607 | p9_free_req(clnt, req); | ||
1608 | error: | ||
1609 | return err; | ||
1610 | } | 1608 | } |
1611 | EXPORT_SYMBOL(p9_client_read); | 1609 | EXPORT_SYMBOL(p9_client_read); |
1612 | 1610 | ||