| .. | .. |
|---|
| 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); |
|---|