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 ffd9e6c2ffc154167e08e9d70fed80c3e617c5f5..9b65509424dc6baf31ebe89bceb7d9ffaf96f5d1 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 c535de5852bf3b04ef3e38c9e707a9f0f0a98e3e..8fab5db16c738a6c365f746e21f702bc4bd2208b 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 e1e05b253daa56e6675ad7a66d2f608a59000190..3ba013e2987f2ee422a7d6b0959f112c43f5b930 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 0e84e6fcf8ab4fdb0fad67b58586218050afbf2f..f833953bab61c6b0625788c156ba9fc87bde533a 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 c7fc01c2d509a5c32d8dfca70746c3ce05ecbd28..f669163d5860f90f3f4543618160f49e1e12af52 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 8d657c2cd6f7937161834e1b784be8a5179cd539..51897427a5346ed2377ec92857154601c24917e3 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 c982e3afe3b4e484e13975406ccfb759b4f3ecb6..69e19fc0afc17114fa3ee0d8dfd94c747864ed34 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 022e1ce63e62eab9bd598235258280d76eccbb6d..c275c83f0aefdd547aeadcccb1f499bfdb921a3e 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 e7fc29b5ad1974c41911da4a92105ec4b840c764..b70d2869340063e0a62cea36b917fbf37b9d2273 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 f3988ef8e9af8ee0d83469e81c9b9d5fa4ec70fe..7255531f63ae279204bd6dd1a592ded789d4ac0e 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 81627892bdd44693da2e942007447c685aa25bc8..cf3c24c8610d38d2673e685dace2354aefa72381 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 799034e0f513d988334280186cbdf255fbf50eb7..d74be4e3f3faf5147f851d20b674d935d035594e 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 17db8c8811fa47acabc158434c39acc25a171d77..f76119f62f1b56b3fde5cc5204df2eccb3f6d7fa 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) {