Skip to content

Commit

Permalink
iov_iter: advancing variants of iov_iter_get_pages{,_alloc}()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Aug 9, 2022
1 parent 3cf42da commit 1ef255e
Show file tree
Hide file tree
Showing 13 changed files with 34 additions and 30 deletions.
4 changes: 1 addition & 3 deletions drivers/vhost/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions fs/ceph/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
6 changes: 2 additions & 4 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions fs/cifs/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions include/linux/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 1 addition & 2 deletions net/core/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions net/core/skmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 1 addition & 2 deletions net/rds/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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++;
Expand Down
4 changes: 1 addition & 3 deletions net/tls/tls_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1352,16 +1352,14 @@ 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) {
rc = -EFAULT;
goto out;
}

iov_iter_advance(from, copied);

length -= copied;
size += copied;
while (copied) {
Expand Down

0 comments on commit 1ef255e

Please sign in to comment.