iov_iter: advancing variants of iov_iter_get_pages{,_alloc}()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Jun 2022 14:28:36 +0000 (10:28 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 9 Aug 2022 02:37:22 +0000 (22:37 -0400)
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>
13 files changed:
drivers/vhost/scsi.c
fs/ceph/file.c
fs/cifs/file.c
fs/cifs/misc.c
fs/direct-io.c
fs/fuse/dev.c
fs/fuse/file.c
fs/nfs/direct.c
include/linux/uio.h
net/core/datagram.c
net/core/skmsg.c
net/rds/message.c
net/tls/tls_sw.c

index ffd9e6c..9b65509 100644 (file)
@@ -643,14 +643,12 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
        size_t offset;
        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);
        /* No pages were pinned */
        if (bytes <= 0)
                return bytes < 0 ? bytes : -EFAULT;
 
-       iov_iter_advance(iter, bytes);
-
        while (bytes) {
                unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes);
                sg_set_page(sg++, pages[npages++], n, offset);
index c535de5..8fab5db 100644 (file)
@@ -95,12 +95,11 @@ static ssize_t __iter_get_bvecs(struct iov_iter *iter, size_t maxsize,
                size_t start;
                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);
                if (bytes < 0)
                        return size ?: bytes;
 
-               iov_iter_advance(iter, bytes);
                size += bytes;
 
                for ( ; bytes; idx++, bvec_idx++) {
index e1e05b2..3ba013e 100644 (file)
@@ -3022,7 +3022,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
                if (ctx->direct_io) {
                        ssize_t result;
 
-                       result = iov_iter_get_pages_alloc(
+                       result = iov_iter_get_pages_alloc2(
                                from, &pagevec, cur_len, &start);
                        if (result < 0) {
                                cifs_dbg(VFS,
@@ -3036,7 +3036,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
                                break;
                        }
                        cur_len = (size_t)result;
-                       iov_iter_advance(from, cur_len);
 
                        nr_pages =
                                (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) {
                        ssize_t result;
 
-                       result = iov_iter_get_pages_alloc(
+                       result = iov_iter_get_pages_alloc2(
                                        &direct_iov, &pagevec,
                                        cur_len, &start);
                        if (result < 0) {
@@ -3774,7 +3773,6 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
                                break;
                        }
                        cur_len = (size_t)result;
-                       iov_iter_advance(&direct_iov, cur_len);
 
                        rdata = cifs_readdata_direct_alloc(
                                        pagevec, cifs_uncached_readv_complete);
index 0e84e6f..f833953 100644 (file)
@@ -1029,7 +1029,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
        saved_len = count;
 
        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) {
                        cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
                        break;
@@ -1041,7 +1041,6 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
                        break;
                }
 
-               iov_iter_advance(iter, rc);
                count -= rc;
                rc += start;
                cur_npages = DIV_ROUND_UP(rc, PAGE_SIZE);
index c7fc01c..f669163 100644 (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;
        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);
 
        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) {
-               iov_iter_advance(sdio->iter, ret);
                ret += sdio->from;
                sdio->head = 0;
                sdio->tail = (ret + PAGE_SIZE - 1) / PAGE_SIZE;
index 8d657c2..5189742 100644 (file)
@@ -730,14 +730,13 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
                }
        } else {
                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)
                        return err;
                BUG_ON(!err);
                cs->len = err;
                cs->offset = off;
                cs->pg = page;
-               iov_iter_advance(cs->iter, err);
        }
 
        return lock_request(cs->req);
index c982e3a..69e19fc 100644 (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) {
                unsigned npages;
                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,
                                        max_pages - ap->num_pages,
                                        &start);
                if (ret < 0)
                        break;
 
-               iov_iter_advance(ii, ret);
                nbytes += ret;
 
                ret += start;
index 022e1ce..c275c83 100644 (file)
@@ -364,13 +364,12 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
                size_t pgbase;
                unsigned npages, i;
 
-               result = iov_iter_get_pages_alloc(iter, &pagevec, 
+               result = iov_iter_get_pages_alloc2(iter, &pagevec,
                                                  rsize, &pgbase);
                if (result < 0)
                        break;
        
                bytes = result;
-               iov_iter_advance(iter, bytes);
                npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
                for (i = 0; i < npages; i++) {
                        struct nfs_page *req;
@@ -812,13 +811,12 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
                size_t pgbase;
                unsigned npages, i;
 
-               result = iov_iter_get_pages_alloc(iter, &pagevec, 
+               result = iov_iter_get_pages_alloc2(iter, &pagevec,
                                                  wsize, &pgbase);
                if (result < 0)
                        break;
 
                bytes = result;
-               iov_iter_advance(iter, bytes);
                npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
                for (i = 0; i < npages; i++) {
                        struct nfs_page *req;
index e7fc29b..b70d286 100644 (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
index f3988ef..7255531 100644 (file)
@@ -632,12 +632,11 @@ int __zerocopy_sg_from_iter(struct msghdr *msg, struct sock *sk,
                if (frag == MAX_SKB_FRAGS)
                        return -EMSGSIZE;
 
-               copied = iov_iter_get_pages(from, pages, length,
+               copied = iov_iter_get_pages2(from, pages, length,
                                            MAX_SKB_FRAGS - frag, &start);
                if (copied < 0)
                        return -EFAULT;
 
-               iov_iter_advance(from, copied);
                length -= copied;
 
                truesize = PAGE_ALIGN(copied + start);
index 8162789..cf3c24c 100644 (file)
@@ -324,14 +324,13 @@ int sk_msg_zerocopy_from_iter(struct sock *sk, struct iov_iter *from,
                        goto out;
                }
 
-               copied = iov_iter_get_pages(from, pages, bytes, maxpages,
+               copied = iov_iter_get_pages2(from, pages, bytes, maxpages,
                                            &offset);
                if (copied <= 0) {
                        ret = -EFAULT;
                        goto out;
                }
 
-               iov_iter_advance(from, copied);
                bytes -= copied;
                msg->sg.size += copied;
 
index 799034e..d74be4e 100644 (file)
@@ -391,7 +391,7 @@ static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *
                size_t start;
                ssize_t copied;
 
-               copied = iov_iter_get_pages(from, &pages, PAGE_SIZE,
+               copied = iov_iter_get_pages2(from, &pages, PAGE_SIZE,
                                            1, &start);
                if (copied < 0) {
                        struct mmpin *mmp;
@@ -405,7 +405,6 @@ static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *
                        goto err;
                }
                total_copied += copied;
-               iov_iter_advance(from, copied);
                length -= copied;
                sg_set_page(sg, pages, copied, start);
                rm->data.op_nents++;
index 17db8c8..f76119f 100644 (file)
@@ -1352,7 +1352,7 @@ static int tls_setup_from_iter(struct iov_iter *from,
                        rc = -EFAULT;
                        goto out;
                }
-               copied = iov_iter_get_pages(from, pages,
+               copied = iov_iter_get_pages2(from, pages,
                                            length,
                                            maxpages, &offset);
                if (copied <= 0) {
@@ -1360,8 +1360,6 @@ static int tls_setup_from_iter(struct iov_iter *from,
                        goto out;
                }
 
-               iov_iter_advance(from, copied);
-
                length -= copied;
                size += copied;
                while (copied) {