diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-01 20:17:51 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:28:25 -0400 |
commit | 070b3656cf228eaaef7b28b59264c5c7cdbdd0fb (patch) | |
tree | 76040fdba3e0703df0be897aba7310332454d60e /net/9p/client.c | |
parent | 4f3b35c157e43107cc7e1f1aa06694e8b22e10bb (diff) |
9p: switch p9_client_write() to passing it struct iov_iter *
... and make it loop until it's done
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/9p/client.c')
-rw-r--r-- | net/9p/client.c | 98 |
1 files changed, 41 insertions, 57 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 9ef5d85f082f..aa38cfeb8615 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1611,69 +1611,53 @@ error: | |||
1611 | EXPORT_SYMBOL(p9_client_read); | 1611 | EXPORT_SYMBOL(p9_client_read); |
1612 | 1612 | ||
1613 | int | 1613 | int |
1614 | p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, | 1614 | p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) |
1615 | u64 offset, u32 count) | ||
1616 | { | 1615 | { |
1617 | int err, rsize; | 1616 | struct p9_client *clnt = fid->clnt; |
1618 | struct p9_client *clnt; | ||
1619 | struct p9_req_t *req; | 1617 | struct p9_req_t *req; |
1620 | struct iov_iter from; | 1618 | int total = 0; |
1621 | union { | 1619 | |
1622 | struct kvec kv; | 1620 | p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n", |
1623 | struct iovec iov; | 1621 | fid->fid, (unsigned long long) offset, |
1624 | } v; | 1622 | iov_iter_count(from)); |
1625 | 1623 | ||
1626 | if (data) { | 1624 | while (iov_iter_count(from)) { |
1627 | v.kv.iov_base = data; | 1625 | int count = iov_iter_count(from); |
1628 | v.kv.iov_len = count; | 1626 | int rsize = fid->iounit; |
1629 | iov_iter_kvec(&from, ITER_KVEC | WRITE, &v.kv, 1, count); | 1627 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) |
1630 | } else { | 1628 | rsize = clnt->msize - P9_IOHDRSZ; |
1631 | v.iov.iov_base = udata; | 1629 | |
1632 | v.iov.iov_len = count; | 1630 | if (count < rsize) |
1633 | iov_iter_init(&from, WRITE, &v.iov, 1, count); | 1631 | rsize = count; |
1634 | } | 1632 | |
1635 | 1633 | /* Don't bother zerocopy for small IO (< 1024) */ | |
1636 | p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n", | 1634 | if (clnt->trans_mod->zc_request && rsize > 1024) { |
1637 | fid->fid, (unsigned long long) offset, count); | 1635 | req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, from, 0, |
1638 | err = 0; | 1636 | rsize, P9_ZC_HDR_SZ, "dqd", |
1639 | clnt = fid->clnt; | 1637 | fid->fid, offset, rsize); |
1640 | 1638 | } else { | |
1641 | rsize = fid->iounit; | 1639 | req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid, |
1642 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | 1640 | offset, rsize, from); |
1643 | rsize = clnt->msize - P9_IOHDRSZ; | 1641 | } |
1642 | if (IS_ERR(req)) { | ||
1643 | *err = PTR_ERR(req); | ||
1644 | break; | ||
1645 | } | ||
1644 | 1646 | ||
1645 | if (count < rsize) | 1647 | *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); |
1646 | rsize = count; | 1648 | if (*err) { |
1649 | trace_9p_protocol_dump(clnt, req->rc); | ||
1650 | p9_free_req(clnt, req); | ||
1651 | } | ||
1647 | 1652 | ||
1648 | /* Don't bother zerocopy for small IO (< 1024) */ | 1653 | p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); |
1649 | if (clnt->trans_mod->zc_request && rsize > 1024) { | ||
1650 | req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, &from, 0, rsize, | ||
1651 | P9_ZC_HDR_SZ, "dqd", | ||
1652 | fid->fid, offset, rsize); | ||
1653 | } else { | ||
1654 | req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid, | ||
1655 | offset, rsize, &from); | ||
1656 | } | ||
1657 | if (IS_ERR(req)) { | ||
1658 | err = PTR_ERR(req); | ||
1659 | goto error; | ||
1660 | } | ||
1661 | 1654 | ||
1662 | err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); | 1655 | p9_free_req(clnt, req); |
1663 | if (err) { | 1656 | iov_iter_advance(from, count); |
1664 | trace_9p_protocol_dump(clnt, req->rc); | 1657 | total += count; |
1665 | goto free_and_error; | 1658 | offset += count; |
1666 | } | 1659 | } |
1667 | 1660 | return total; | |
1668 | p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); | ||
1669 | |||
1670 | p9_free_req(clnt, req); | ||
1671 | return count; | ||
1672 | |||
1673 | free_and_error: | ||
1674 | p9_free_req(clnt, req); | ||
1675 | error: | ||
1676 | return err; | ||
1677 | } | 1661 | } |
1678 | EXPORT_SYMBOL(p9_client_write); | 1662 | EXPORT_SYMBOL(p9_client_write); |
1679 | 1663 | ||