9p: convert to advancing variant of iov_iter_get_pages_alloc()
that one is somewhat clumsier than usual and needs serious testing. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
dc5801f60b
commit
7f02464739
|
@ -1491,7 +1491,7 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
|||
struct p9_client *clnt = fid->clnt;
|
||||
struct p9_req_t *req;
|
||||
int count = iov_iter_count(to);
|
||||
int rsize, non_zc = 0;
|
||||
int rsize, received, non_zc = 0;
|
||||
char *dataptr;
|
||||
|
||||
*err = 0;
|
||||
|
@ -1520,36 +1520,40 @@ 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", &count, &dataptr);
|
||||
"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_tag_remove(clnt, req);
|
||||
return 0;
|
||||
}
|
||||
if (rsize < count) {
|
||||
pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
|
||||
count = rsize;
|
||||
if (rsize < received) {
|
||||
pr_err("bogus RREAD count (%d > %d)\n", received, rsize);
|
||||
received = rsize;
|
||||
}
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
|
||||
|
||||
if (non_zc) {
|
||||
int n = copy_to_iter(dataptr, count, to);
|
||||
int n = copy_to_iter(dataptr, received, to);
|
||||
|
||||
if (n != count) {
|
||||
if (n != received) {
|
||||
*err = -EFAULT;
|
||||
p9_tag_remove(clnt, req);
|
||||
return n;
|
||||
}
|
||||
} else {
|
||||
iov_iter_advance(to, count);
|
||||
iov_iter_revert(to, count - received - iov_iter_count(to));
|
||||
}
|
||||
p9_tag_remove(clnt, req);
|
||||
return count;
|
||||
return received;
|
||||
}
|
||||
EXPORT_SYMBOL(p9_client_read_once);
|
||||
|
||||
|
@ -1567,6 +1571,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
|||
while (iov_iter_count(from)) {
|
||||
int count = iov_iter_count(from);
|
||||
int rsize = fid->iounit;
|
||||
int written;
|
||||
|
||||
if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
|
||||
rsize = clnt->msize - P9_IOHDRSZ;
|
||||
|
@ -1584,27 +1589,29 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
|||
offset, rsize, from);
|
||||
}
|
||||
if (IS_ERR(req)) {
|
||||
iov_iter_revert(from, count - iov_iter_count(from));
|
||||
*err = PTR_ERR(req);
|
||||
break;
|
||||
}
|
||||
|
||||
*err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
|
||||
*err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &written);
|
||||
if (*err) {
|
||||
iov_iter_revert(from, count - iov_iter_count(from));
|
||||
trace_9p_protocol_dump(clnt, &req->rc);
|
||||
p9_tag_remove(clnt, req);
|
||||
break;
|
||||
}
|
||||
if (rsize < count) {
|
||||
pr_err("bogus RWRITE count (%d > %d)\n", count, rsize);
|
||||
count = rsize;
|
||||
if (rsize < written) {
|
||||
pr_err("bogus RWRITE count (%d > %d)\n", written, rsize);
|
||||
written = rsize;
|
||||
}
|
||||
|
||||
p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
|
||||
|
||||
p9_tag_remove(clnt, req);
|
||||
iov_iter_advance(from, count);
|
||||
total += count;
|
||||
offset += count;
|
||||
iov_iter_revert(from, count - written - iov_iter_count(from));
|
||||
total += written;
|
||||
offset += written;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
|
|
@ -63,9 +63,8 @@ static size_t
|
|||
pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
|
||||
{
|
||||
size_t len = min(pdu->capacity - pdu->size, size);
|
||||
struct iov_iter i = *from;
|
||||
|
||||
if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, &i))
|
||||
if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, from))
|
||||
len = 0;
|
||||
|
||||
pdu->size += len;
|
||||
|
|
|
@ -331,7 +331,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
|
|||
if (err == -ERESTARTSYS)
|
||||
return err;
|
||||
}
|
||||
n = iov_iter_get_pages_alloc(data, pages, count, offs);
|
||||
n = iov_iter_get_pages_alloc2(data, pages, count, offs);
|
||||
if (n < 0)
|
||||
return n;
|
||||
*need_drop = 1;
|
||||
|
@ -373,6 +373,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
|
|||
(*pages)[index] = kmap_to_page(p);
|
||||
p += PAGE_SIZE;
|
||||
}
|
||||
iov_iter_advance(data, len);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue