iov_iter: advancing variants of iov_iter_get_pages{,_alloc}()

Most of the users immediately follow successful iov_iter_get_pages()
with advancing by the amount it had returned.

Provide inline wrappers doing that, convert trivial open-coded
uses of those.

BTW, iov_iter_get_pages() never returns more than it had been asked
to; such checks in cifs ought to be removed someday...

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2022-06-09 10:28:36 -04:00
parent 3cf42da327
commit 1ef255e257
13 changed files with 34 additions and 30 deletions

View File

@ -643,14 +643,12 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
size_t offset; size_t offset;
unsigned int npages = 0; unsigned int npages = 0;
bytes = iov_iter_get_pages(iter, pages, LONG_MAX, bytes = iov_iter_get_pages2(iter, pages, LONG_MAX,
VHOST_SCSI_PREALLOC_UPAGES, &offset); VHOST_SCSI_PREALLOC_UPAGES, &offset);
/* No pages were pinned */ /* No pages were pinned */
if (bytes <= 0) if (bytes <= 0)
return bytes < 0 ? bytes : -EFAULT; return bytes < 0 ? bytes : -EFAULT;
iov_iter_advance(iter, bytes);
while (bytes) { while (bytes) {
unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes); unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes);
sg_set_page(sg++, pages[npages++], n, offset); sg_set_page(sg++, pages[npages++], n, offset);

View File

@ -95,12 +95,11 @@ static ssize_t __iter_get_bvecs(struct iov_iter *iter, size_t maxsize,
size_t start; size_t start;
int idx = 0; int idx = 0;
bytes = iov_iter_get_pages(iter, pages, maxsize - size, bytes = iov_iter_get_pages2(iter, pages, maxsize - size,
ITER_GET_BVECS_PAGES, &start); ITER_GET_BVECS_PAGES, &start);
if (bytes < 0) if (bytes < 0)
return size ?: bytes; return size ?: bytes;
iov_iter_advance(iter, bytes);
size += bytes; size += bytes;
for ( ; bytes; idx++, bvec_idx++) { for ( ; bytes; idx++, bvec_idx++) {

View File

@ -3022,7 +3022,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
if (ctx->direct_io) { if (ctx->direct_io) {
ssize_t result; ssize_t result;
result = iov_iter_get_pages_alloc( result = iov_iter_get_pages_alloc2(
from, &pagevec, cur_len, &start); from, &pagevec, cur_len, &start);
if (result < 0) { if (result < 0) {
cifs_dbg(VFS, cifs_dbg(VFS,
@ -3036,7 +3036,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
break; break;
} }
cur_len = (size_t)result; cur_len = (size_t)result;
iov_iter_advance(from, cur_len);
nr_pages = nr_pages =
(cur_len + start + PAGE_SIZE - 1) / PAGE_SIZE; (cur_len + start + PAGE_SIZE - 1) / PAGE_SIZE;
@ -3758,7 +3757,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
if (ctx->direct_io) { if (ctx->direct_io) {
ssize_t result; ssize_t result;
result = iov_iter_get_pages_alloc( result = iov_iter_get_pages_alloc2(
&direct_iov, &pagevec, &direct_iov, &pagevec,
cur_len, &start); cur_len, &start);
if (result < 0) { if (result < 0) {
@ -3774,7 +3773,6 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
break; break;
} }
cur_len = (size_t)result; cur_len = (size_t)result;
iov_iter_advance(&direct_iov, cur_len);
rdata = cifs_readdata_direct_alloc( rdata = cifs_readdata_direct_alloc(
pagevec, cifs_uncached_readv_complete); pagevec, cifs_uncached_readv_complete);

View File

@ -1029,7 +1029,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
saved_len = count; saved_len = count;
while (count && npages < max_pages) { while (count && npages < max_pages) {
rc = iov_iter_get_pages(iter, pages, count, max_pages, &start); rc = iov_iter_get_pages2(iter, pages, count, max_pages, &start);
if (rc < 0) { if (rc < 0) {
cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc); cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
break; break;
@ -1041,7 +1041,6 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
break; break;
} }
iov_iter_advance(iter, rc);
count -= rc; count -= rc;
rc += start; rc += start;
cur_npages = DIV_ROUND_UP(rc, PAGE_SIZE); cur_npages = DIV_ROUND_UP(rc, PAGE_SIZE);

View File

@ -169,7 +169,7 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio)
const enum req_op dio_op = dio->opf & REQ_OP_MASK; const enum req_op dio_op = dio->opf & REQ_OP_MASK;
ssize_t ret; ssize_t ret;
ret = iov_iter_get_pages(sdio->iter, dio->pages, LONG_MAX, DIO_PAGES, ret = iov_iter_get_pages2(sdio->iter, dio->pages, LONG_MAX, DIO_PAGES,
&sdio->from); &sdio->from);
if (ret < 0 && sdio->blocks_available && dio_op == REQ_OP_WRITE) { if (ret < 0 && sdio->blocks_available && dio_op == REQ_OP_WRITE) {
@ -191,7 +191,6 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio)
} }
if (ret >= 0) { if (ret >= 0) {
iov_iter_advance(sdio->iter, ret);
ret += sdio->from; ret += sdio->from;
sdio->head = 0; sdio->head = 0;
sdio->tail = (ret + PAGE_SIZE - 1) / PAGE_SIZE; sdio->tail = (ret + PAGE_SIZE - 1) / PAGE_SIZE;

View File

@ -730,14 +730,13 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
} }
} else { } else {
size_t off; size_t off;
err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); err = iov_iter_get_pages2(cs->iter, &page, PAGE_SIZE, 1, &off);
if (err < 0) if (err < 0)
return err; return err;
BUG_ON(!err); BUG_ON(!err);
cs->len = err; cs->len = err;
cs->offset = off; cs->offset = off;
cs->pg = page; cs->pg = page;
iov_iter_advance(cs->iter, err);
} }
return lock_request(cs->req); return lock_request(cs->req);

View File

@ -1401,14 +1401,13 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
while (nbytes < *nbytesp && ap->num_pages < max_pages) { while (nbytes < *nbytesp && ap->num_pages < max_pages) {
unsigned npages; unsigned npages;
size_t start; size_t start;
ret = iov_iter_get_pages(ii, &ap->pages[ap->num_pages], ret = iov_iter_get_pages2(ii, &ap->pages[ap->num_pages],
*nbytesp - nbytes, *nbytesp - nbytes,
max_pages - ap->num_pages, max_pages - ap->num_pages,
&start); &start);
if (ret < 0) if (ret < 0)
break; break;
iov_iter_advance(ii, ret);
nbytes += ret; nbytes += ret;
ret += start; ret += start;

View File

@ -364,13 +364,12 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
size_t pgbase; size_t pgbase;
unsigned npages, i; unsigned npages, i;
result = iov_iter_get_pages_alloc(iter, &pagevec, result = iov_iter_get_pages_alloc2(iter, &pagevec,
rsize, &pgbase); rsize, &pgbase);
if (result < 0) if (result < 0)
break; break;
bytes = result; bytes = result;
iov_iter_advance(iter, bytes);
npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE; npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
for (i = 0; i < npages; i++) { for (i = 0; i < npages; i++) {
struct nfs_page *req; struct nfs_page *req;
@ -812,13 +811,12 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
size_t pgbase; size_t pgbase;
unsigned npages, i; unsigned npages, i;
result = iov_iter_get_pages_alloc(iter, &pagevec, result = iov_iter_get_pages_alloc2(iter, &pagevec,
wsize, &pgbase); wsize, &pgbase);
if (result < 0) if (result < 0)
break; break;
bytes = result; bytes = result;
iov_iter_advance(iter, bytes);
npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE; npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
for (i = 0; i < npages; i++) { for (i = 0; i < npages; i++) {
struct nfs_page *req; struct nfs_page *req;

View File

@ -351,4 +351,24 @@ static inline void iov_iter_ubuf(struct iov_iter *i, unsigned int direction,
}; };
} }
static inline ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages,
size_t maxsize, unsigned maxpages, size_t *start)
{
ssize_t res = iov_iter_get_pages(i, pages, maxsize, maxpages, start);
if (res >= 0)
iov_iter_advance(i, res);
return res;
}
static inline ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i, struct page ***pages,
size_t maxsize, size_t *start)
{
ssize_t res = iov_iter_get_pages_alloc(i, pages, maxsize, start);
if (res >= 0)
iov_iter_advance(i, res);
return res;
}
#endif #endif

View File

@ -632,12 +632,11 @@ int __zerocopy_sg_from_iter(struct msghdr *msg, struct sock *sk,
if (frag == MAX_SKB_FRAGS) if (frag == MAX_SKB_FRAGS)
return -EMSGSIZE; return -EMSGSIZE;
copied = iov_iter_get_pages(from, pages, length, copied = iov_iter_get_pages2(from, pages, length,
MAX_SKB_FRAGS - frag, &start); MAX_SKB_FRAGS - frag, &start);
if (copied < 0) if (copied < 0)
return -EFAULT; return -EFAULT;
iov_iter_advance(from, copied);
length -= copied; length -= copied;
truesize = PAGE_ALIGN(copied + start); truesize = PAGE_ALIGN(copied + start);

View File

@ -324,14 +324,13 @@ int sk_msg_zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
goto out; goto out;
} }
copied = iov_iter_get_pages(from, pages, bytes, maxpages, copied = iov_iter_get_pages2(from, pages, bytes, maxpages,
&offset); &offset);
if (copied <= 0) { if (copied <= 0) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
} }
iov_iter_advance(from, copied);
bytes -= copied; bytes -= copied;
msg->sg.size += copied; msg->sg.size += copied;

View File

@ -391,7 +391,7 @@ static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *
size_t start; size_t start;
ssize_t copied; ssize_t copied;
copied = iov_iter_get_pages(from, &pages, PAGE_SIZE, copied = iov_iter_get_pages2(from, &pages, PAGE_SIZE,
1, &start); 1, &start);
if (copied < 0) { if (copied < 0) {
struct mmpin *mmp; struct mmpin *mmp;
@ -405,7 +405,6 @@ static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *
goto err; goto err;
} }
total_copied += copied; total_copied += copied;
iov_iter_advance(from, copied);
length -= copied; length -= copied;
sg_set_page(sg, pages, copied, start); sg_set_page(sg, pages, copied, start);
rm->data.op_nents++; rm->data.op_nents++;

View File

@ -1352,7 +1352,7 @@ static int tls_setup_from_iter(struct iov_iter *from,
rc = -EFAULT; rc = -EFAULT;
goto out; goto out;
} }
copied = iov_iter_get_pages(from, pages, copied = iov_iter_get_pages2(from, pages,
length, length,
maxpages, &offset); maxpages, &offset);
if (copied <= 0) { if (copied <= 0) {
@ -1360,8 +1360,6 @@ static int tls_setup_from_iter(struct iov_iter *from,
goto out; goto out;
} }
iov_iter_advance(from, copied);
length -= copied; length -= copied;
size += copied; size += copied;
while (copied) { while (copied) {