.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * net/9p/clnt.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com> |
---|
7 | 8 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License version 2 |
---|
11 | | - * as published by the Free Software Foundation. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, |
---|
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | | - * GNU General Public License for more details. |
---|
17 | | - * |
---|
18 | | - * You should have received a copy of the GNU General Public License |
---|
19 | | - * along with this program; if not, write to: |
---|
20 | | - * Free Software Foundation |
---|
21 | | - * 51 Franklin Street, Fifth Floor |
---|
22 | | - * Boston, MA 02111-1301 USA |
---|
23 | | - * |
---|
24 | 9 | */ |
---|
25 | 10 | |
---|
26 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
828 | 813 | * @uodata: source for zero copy write |
---|
829 | 814 | * @inlen: read buffer size |
---|
830 | 815 | * @olen: write buffer size |
---|
831 | | - * @hdrlen: reader header size, This is the size of response protocol data |
---|
| 816 | + * @in_hdrlen: reader header size, This is the size of response protocol data |
---|
832 | 817 | * @fmt: protocol format string (see protocol.c) |
---|
833 | 818 | * |
---|
834 | 819 | * Returns request structure (which client must free using p9_tag_remove) |
---|
.. | .. |
---|
908 | 893 | struct p9_fid *fid; |
---|
909 | 894 | |
---|
910 | 895 | p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt); |
---|
911 | | - fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); |
---|
| 896 | + fid = kzalloc(sizeof(struct p9_fid), GFP_KERNEL); |
---|
912 | 897 | if (!fid) |
---|
913 | 898 | return NULL; |
---|
914 | 899 | |
---|
915 | | - memset(&fid->qid, 0, sizeof(struct p9_qid)); |
---|
916 | 900 | fid->mode = -1; |
---|
917 | 901 | fid->uid = current_fsuid(); |
---|
918 | 902 | fid->clnt = clnt; |
---|
919 | | - fid->rdir = NULL; |
---|
920 | | - fid->fid = 0; |
---|
921 | 903 | |
---|
922 | 904 | idr_preload(GFP_KERNEL); |
---|
923 | 905 | spin_lock_irq(&clnt->lock); |
---|
.. | .. |
---|
1566 | 1548 | int |
---|
1567 | 1549 | p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) |
---|
1568 | 1550 | { |
---|
1569 | | - struct p9_client *clnt = fid->clnt; |
---|
1570 | | - struct p9_req_t *req; |
---|
1571 | 1551 | int total = 0; |
---|
1572 | 1552 | *err = 0; |
---|
1573 | 1553 | |
---|
1574 | | - p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", |
---|
1575 | | - fid->fid, (unsigned long long) offset, (int)iov_iter_count(to)); |
---|
1576 | | - |
---|
1577 | 1554 | while (iov_iter_count(to)) { |
---|
1578 | | - int count = iov_iter_count(to); |
---|
1579 | | - int rsize, non_zc = 0; |
---|
1580 | | - char *dataptr; |
---|
| 1555 | + int count; |
---|
1581 | 1556 | |
---|
1582 | | - rsize = fid->iounit; |
---|
1583 | | - if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) |
---|
1584 | | - rsize = clnt->msize - P9_IOHDRSZ; |
---|
1585 | | - |
---|
1586 | | - if (count < rsize) |
---|
1587 | | - rsize = count; |
---|
1588 | | - |
---|
1589 | | - /* Don't bother zerocopy for small IO (< 1024) */ |
---|
1590 | | - if (clnt->trans_mod->zc_request && rsize > 1024) { |
---|
1591 | | - /* |
---|
1592 | | - * response header len is 11 |
---|
1593 | | - * PDU Header(7) + IO Size (4) |
---|
1594 | | - */ |
---|
1595 | | - req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize, |
---|
1596 | | - 0, 11, "dqd", fid->fid, |
---|
1597 | | - offset, rsize); |
---|
1598 | | - } else { |
---|
1599 | | - non_zc = 1; |
---|
1600 | | - req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, |
---|
1601 | | - rsize); |
---|
1602 | | - } |
---|
1603 | | - if (IS_ERR(req)) { |
---|
1604 | | - *err = PTR_ERR(req); |
---|
| 1557 | + count = p9_client_read_once(fid, offset, to, err); |
---|
| 1558 | + if (!count || *err) |
---|
1605 | 1559 | break; |
---|
1606 | | - } |
---|
1607 | | - |
---|
1608 | | - *err = p9pdu_readf(&req->rc, clnt->proto_version, |
---|
1609 | | - "D", &count, &dataptr); |
---|
1610 | | - if (*err) { |
---|
1611 | | - trace_9p_protocol_dump(clnt, &req->rc); |
---|
1612 | | - p9_tag_remove(clnt, req); |
---|
1613 | | - break; |
---|
1614 | | - } |
---|
1615 | | - if (rsize < count) { |
---|
1616 | | - pr_err("bogus RREAD count (%d > %d)\n", count, rsize); |
---|
1617 | | - count = rsize; |
---|
1618 | | - } |
---|
1619 | | - |
---|
1620 | | - p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); |
---|
1621 | | - if (!count) { |
---|
1622 | | - p9_tag_remove(clnt, req); |
---|
1623 | | - break; |
---|
1624 | | - } |
---|
1625 | | - |
---|
1626 | | - if (non_zc) { |
---|
1627 | | - int n = copy_to_iter(dataptr, count, to); |
---|
1628 | | - total += n; |
---|
1629 | | - offset += n; |
---|
1630 | | - if (n != count) { |
---|
1631 | | - *err = -EFAULT; |
---|
1632 | | - p9_tag_remove(clnt, req); |
---|
1633 | | - break; |
---|
1634 | | - } |
---|
1635 | | - } else { |
---|
1636 | | - iov_iter_advance(to, count); |
---|
1637 | | - total += count; |
---|
1638 | | - offset += count; |
---|
1639 | | - } |
---|
1640 | | - p9_tag_remove(clnt, req); |
---|
| 1560 | + offset += count; |
---|
| 1561 | + total += count; |
---|
1641 | 1562 | } |
---|
1642 | 1563 | return total; |
---|
1643 | 1564 | } |
---|
1644 | 1565 | EXPORT_SYMBOL(p9_client_read); |
---|
| 1566 | + |
---|
| 1567 | +int |
---|
| 1568 | +p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, |
---|
| 1569 | + int *err) |
---|
| 1570 | +{ |
---|
| 1571 | + struct p9_client *clnt = fid->clnt; |
---|
| 1572 | + struct p9_req_t *req; |
---|
| 1573 | + int count = iov_iter_count(to); |
---|
| 1574 | + int rsize, non_zc = 0; |
---|
| 1575 | + char *dataptr; |
---|
| 1576 | + |
---|
| 1577 | + *err = 0; |
---|
| 1578 | + p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", |
---|
| 1579 | + fid->fid, (unsigned long long) offset, (int)iov_iter_count(to)); |
---|
| 1580 | + |
---|
| 1581 | + rsize = fid->iounit; |
---|
| 1582 | + if (!rsize || rsize > clnt->msize - P9_IOHDRSZ) |
---|
| 1583 | + rsize = clnt->msize - P9_IOHDRSZ; |
---|
| 1584 | + |
---|
| 1585 | + if (count < rsize) |
---|
| 1586 | + rsize = count; |
---|
| 1587 | + |
---|
| 1588 | + /* Don't bother zerocopy for small IO (< 1024) */ |
---|
| 1589 | + if (clnt->trans_mod->zc_request && rsize > 1024) { |
---|
| 1590 | + /* response header len is 11 |
---|
| 1591 | + * PDU Header(7) + IO Size (4) |
---|
| 1592 | + */ |
---|
| 1593 | + req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize, |
---|
| 1594 | + 0, 11, "dqd", fid->fid, |
---|
| 1595 | + offset, rsize); |
---|
| 1596 | + } else { |
---|
| 1597 | + non_zc = 1; |
---|
| 1598 | + req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, |
---|
| 1599 | + rsize); |
---|
| 1600 | + } |
---|
| 1601 | + if (IS_ERR(req)) { |
---|
| 1602 | + *err = PTR_ERR(req); |
---|
| 1603 | + return 0; |
---|
| 1604 | + } |
---|
| 1605 | + |
---|
| 1606 | + *err = p9pdu_readf(&req->rc, clnt->proto_version, |
---|
| 1607 | + "D", &count, &dataptr); |
---|
| 1608 | + if (*err) { |
---|
| 1609 | + trace_9p_protocol_dump(clnt, &req->rc); |
---|
| 1610 | + p9_tag_remove(clnt, req); |
---|
| 1611 | + return 0; |
---|
| 1612 | + } |
---|
| 1613 | + if (rsize < count) { |
---|
| 1614 | + pr_err("bogus RREAD count (%d > %d)\n", count, rsize); |
---|
| 1615 | + count = rsize; |
---|
| 1616 | + } |
---|
| 1617 | + |
---|
| 1618 | + p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); |
---|
| 1619 | + |
---|
| 1620 | + if (non_zc) { |
---|
| 1621 | + int n = copy_to_iter(dataptr, count, to); |
---|
| 1622 | + |
---|
| 1623 | + if (n != count) { |
---|
| 1624 | + *err = -EFAULT; |
---|
| 1625 | + p9_tag_remove(clnt, req); |
---|
| 1626 | + return n; |
---|
| 1627 | + } |
---|
| 1628 | + } else { |
---|
| 1629 | + iov_iter_advance(to, count); |
---|
| 1630 | + } |
---|
| 1631 | + p9_tag_remove(clnt, req); |
---|
| 1632 | + return count; |
---|
| 1633 | +} |
---|
| 1634 | +EXPORT_SYMBOL(p9_client_read_once); |
---|
1645 | 1635 | |
---|
1646 | 1636 | int |
---|
1647 | 1637 | p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) |
---|
.. | .. |
---|
2090 | 2080 | struct kvec kv = {.iov_base = data, .iov_len = count}; |
---|
2091 | 2081 | struct iov_iter to; |
---|
2092 | 2082 | |
---|
2093 | | - iov_iter_kvec(&to, READ | ITER_KVEC, &kv, 1, count); |
---|
| 2083 | + iov_iter_kvec(&to, READ, &kv, 1, count); |
---|
2094 | 2084 | |
---|
2095 | 2085 | p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", |
---|
2096 | 2086 | fid->fid, (unsigned long long) offset, count); |
---|