Skip to content

Commit 388f696

Browse files
l29ahDominique Martinet
authored andcommitted
9pnet: allow making incomplete read requests
A user doesn't necessarily want to wait for all the requested data to be available, since the waiting time for each request is unbounded. The new method permits sending one read request at a time and getting the response ASAP, allowing to use 9pnet with synthetic file systems representing arbitrary data streams. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Sergey Alirzaev <[email protected]> Signed-off-by: Dominique Martinet <[email protected]>
1 parent 5195881 commit 388f696

File tree

2 files changed

+75
-61
lines changed

2 files changed

+75
-61
lines changed

include/net/9p/client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ int p9_client_fsync(struct p9_fid *fid, int datasync);
200200
int p9_client_remove(struct p9_fid *fid);
201201
int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
202202
int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err);
203+
int p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
204+
int *err);
203205
int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err);
204206
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset);
205207
int p9dirent_read(struct p9_client *clnt, char *buf, int len,

net/9p/client.c

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,82 +1549,94 @@ EXPORT_SYMBOL(p9_client_unlinkat);
15491549
int
15501550
p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
15511551
{
1552-
struct p9_client *clnt = fid->clnt;
1553-
struct p9_req_t *req;
15541552
int total = 0;
15551553
*err = 0;
15561554

1555+
while (iov_iter_count(to)) {
1556+
int count;
1557+
1558+
count = p9_client_read_once(fid, offset, to, err);
1559+
if (!count || *err)
1560+
break;
1561+
offset += count;
1562+
total += count;
1563+
}
1564+
return total;
1565+
}
1566+
EXPORT_SYMBOL(p9_client_read);
1567+
1568+
int
1569+
p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
1570+
int *err)
1571+
{
1572+
struct p9_client *clnt = fid->clnt;
1573+
struct p9_req_t *req;
1574+
int count = iov_iter_count(to);
1575+
int rsize, non_zc = 0;
1576+
char *dataptr;
1577+
1578+
*err = 0;
15571579
p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
15581580
fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
15591581

1560-
while (iov_iter_count(to)) {
1561-
int count = iov_iter_count(to);
1562-
int rsize, non_zc = 0;
1563-
char *dataptr;
1582+
rsize = fid->iounit;
1583+
if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
1584+
rsize = clnt->msize - P9_IOHDRSZ;
15641585

1565-
rsize = fid->iounit;
1566-
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1567-
rsize = clnt->msize - P9_IOHDRSZ;
1586+
if (count < rsize)
1587+
rsize = count;
15681588

1569-
if (count < rsize)
1570-
rsize = count;
1589+
/* Don't bother zerocopy for small IO (< 1024) */
1590+
if (clnt->trans_mod->zc_request && rsize > 1024) {
1591+
/* response header len is 11
1592+
* PDU Header(7) + IO Size (4)
1593+
*/
1594+
req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
1595+
0, 11, "dqd", fid->fid,
1596+
offset, rsize);
1597+
} else {
1598+
non_zc = 1;
1599+
req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1600+
rsize);
1601+
}
1602+
if (IS_ERR(req)) {
1603+
*err = PTR_ERR(req);
1604+
return 0;
1605+
}
15711606

1572-
/* Don't bother zerocopy for small IO (< 1024) */
1573-
if (clnt->trans_mod->zc_request && rsize > 1024) {
1574-
/*
1575-
* response header len is 11
1576-
* PDU Header(7) + IO Size (4)
1577-
*/
1578-
req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
1579-
0, 11, "dqd", fid->fid,
1580-
offset, rsize);
1581-
} else {
1582-
non_zc = 1;
1583-
req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1584-
rsize);
1585-
}
1586-
if (IS_ERR(req)) {
1587-
*err = PTR_ERR(req);
1588-
break;
1589-
}
1607+
*err = p9pdu_readf(&req->rc, clnt->proto_version,
1608+
"D", &count, &dataptr);
1609+
if (*err) {
1610+
trace_9p_protocol_dump(clnt, &req->rc);
1611+
p9_tag_remove(clnt, req);
1612+
return 0;
1613+
}
1614+
if (rsize < count) {
1615+
pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
1616+
count = rsize;
1617+
}
15901618

1591-
*err = p9pdu_readf(&req->rc, clnt->proto_version,
1592-
"D", &count, &dataptr);
1593-
if (*err) {
1594-
trace_9p_protocol_dump(clnt, &req->rc);
1595-
p9_tag_remove(clnt, req);
1596-
break;
1597-
}
1598-
if (rsize < count) {
1599-
pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
1600-
count = rsize;
1601-
}
1619+
p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1620+
if (!count) {
1621+
p9_tag_remove(clnt, req);
1622+
return 0;
1623+
}
16021624

1603-
p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1604-
if (!count) {
1605-
p9_tag_remove(clnt, req);
1606-
break;
1607-
}
1625+
if (non_zc) {
1626+
int n = copy_to_iter(dataptr, count, to);
16081627

1609-
if (non_zc) {
1610-
int n = copy_to_iter(dataptr, count, to);
1611-
total += n;
1612-
offset += n;
1613-
if (n != count) {
1614-
*err = -EFAULT;
1615-
p9_tag_remove(clnt, req);
1616-
break;
1617-
}
1618-
} else {
1619-
iov_iter_advance(to, count);
1620-
total += count;
1621-
offset += count;
1628+
if (n != count) {
1629+
*err = -EFAULT;
1630+
p9_tag_remove(clnt, req);
1631+
return n;
16221632
}
1623-
p9_tag_remove(clnt, req);
1633+
} else {
1634+
iov_iter_advance(to, count);
16241635
}
1625-
return total;
1636+
p9_tag_remove(clnt, req);
1637+
return count;
16261638
}
1627-
EXPORT_SYMBOL(p9_client_read);
1639+
EXPORT_SYMBOL(p9_client_read_once);
16281640

16291641
int
16301642
p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)

0 commit comments

Comments
 (0)