mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									3cf42da327
								
							
						
					
					
						commit
						1ef255e257
					
				
					 13 changed files with 34 additions and 30 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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++;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue