Can you try the attached? I've also put it on my branch here: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=netfs-fixes David --- 9p: Don't revert the I/O iterator after reading Don't revert the I/O iterator before returning from p9_client_read_once(). netfslib doesn't require the reversion and nor doed 9P directory reading. Make p9_client_read() use a temporary iterator to call down into p9_client_read_once(), and advance that by the amount read. Reported-by: Manu Bretelle <chantr4@xxxxxxxxx> Reported-by: Eduard Zingerman <eddyz87@xxxxxxxxx> Reported-by: Leon Romanovsky <leon@xxxxxxxxxx> Signed-off-by: David Howells <dhowells@xxxxxxxxxx> cc: Eric Van Hensbergen <ericvh@xxxxxxxxxx> cc: Latchesar Ionkov <lucho@xxxxxxxxxx> cc: Dominique Martinet <asmadeus@xxxxxxxxxxxxx> cc: Christian Schoenebeck <linux_oss@xxxxxxxxxxxxx> cc: v9fs@xxxxxxxxxxxxxxx cc: netfs@xxxxxxxxxxxxxxx cc: linux-fsdevel@xxxxxxxxxxxxxxx --- net/9p/client.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index 5cd94721d974..be59b0a94eaf 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1519,13 +1519,15 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err) *err = 0; while (iov_iter_count(to)) { + struct iov_iter tmp = *to; int count; - count = p9_client_read_once(fid, offset, to, err); + count = p9_client_read_once(fid, offset, &tmp, err); if (!count || *err) break; offset += count; total += count; + iov_iter_advance(to, count); } return total; } @@ -1567,16 +1569,12 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, } if (IS_ERR(req)) { *err = PTR_ERR(req); - if (!non_zc) - iov_iter_revert(to, count - iov_iter_count(to)); return 0; } *err = p9pdu_readf(&req->rc, clnt->proto_version, "D", &received, &dataptr); if (*err) { - if (!non_zc) - iov_iter_revert(to, count - iov_iter_count(to)); trace_9p_protocol_dump(clnt, &req->rc); p9_req_put(clnt, req); return 0; @@ -1596,8 +1594,6 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, p9_req_put(clnt, req); return n; } - } else { - iov_iter_revert(to, count - received - iov_iter_count(to)); } p9_req_put(clnt, req); return received;