Skip to content

Commit f30adc0

Browse files
committed
Merge tag 'pull-work.iov_iter-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more iov_iter updates from Al Viro: - more new_sync_{read,write}() speedups - ITER_UBUF introduction - ITER_PIPE cleanups - unification of iov_iter_get_pages/iov_iter_get_pages_alloc and switching them to advancing semantics - making ITER_PIPE take high-order pages without splitting them - handling copy_page_from_iter() for high-order pages properly * tag 'pull-work.iov_iter-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (32 commits) fix copy_page_from_iter() for compound destinations hugetlbfs: copy_page_to_iter() can deal with compound pages copy_page_to_iter(): don't split high-order page in case of ITER_PIPE expand those iov_iter_advance()... pipe_get_pages(): switch to append_pipe() get rid of non-advancing variants ceph: switch the last caller of iov_iter_get_pages_alloc() 9p: convert to advancing variant of iov_iter_get_pages_alloc() af_alg_make_sg(): switch to advancing variant of iov_iter_get_pages() iter_to_pipe(): switch to advancing variant of iov_iter_get_pages() block: convert to advancing variants of iov_iter_get_pages{,_alloc}() iov_iter: advancing variants of iov_iter_get_pages{,_alloc}() iov_iter: saner helper for page array allocation fold __pipe_get_pages() into pipe_get_pages() ITER_XARRAY: don't open-code DIV_ROUND_UP() unify the rest of iov_iter_get_pages()/iov_iter_get_pages_alloc() guts unify xarray_get_pages() and xarray_get_pages_alloc() unify pipe_get_pages() and pipe_get_pages_alloc() iov_iter_get_pages(): sanity-check arguments iov_iter_get_pages_alloc(): lift freeing pages array on failure exits into wrapper ...
2 parents 5d5d353 + c03f05f commit f30adc0

File tree

30 files changed

+508
-621
lines changed

30 files changed

+508
-621
lines changed

block/bio.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12001200
struct page **pages = (struct page **)bv;
12011201
ssize_t size, left;
12021202
unsigned len, i = 0;
1203-
size_t offset;
1203+
size_t offset, trim;
12041204
int ret = 0;
12051205

12061206
/*
@@ -1218,16 +1218,19 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12181218
* result to ensure the bio's total size is correct. The remainder of
12191219
* the iov data will be picked up in the next bio iteration.
12201220
*/
1221-
size = iov_iter_get_pages(iter, pages, UINT_MAX - bio->bi_iter.bi_size,
1221+
size = iov_iter_get_pages2(iter, pages, UINT_MAX - bio->bi_iter.bi_size,
12221222
nr_pages, &offset);
1223-
if (size > 0) {
1224-
nr_pages = DIV_ROUND_UP(offset + size, PAGE_SIZE);
1225-
size = ALIGN_DOWN(size, bdev_logical_block_size(bio->bi_bdev));
1226-
} else
1227-
nr_pages = 0;
1228-
1229-
if (unlikely(size <= 0)) {
1230-
ret = size ? size : -EFAULT;
1223+
if (unlikely(size <= 0))
1224+
return size ? size : -EFAULT;
1225+
1226+
nr_pages = DIV_ROUND_UP(offset + size, PAGE_SIZE);
1227+
1228+
trim = size & (bdev_logical_block_size(bio->bi_bdev) - 1);
1229+
iov_iter_revert(iter, trim);
1230+
1231+
size -= trim;
1232+
if (unlikely(!size)) {
1233+
ret = -EFAULT;
12311234
goto out;
12321235
}
12331236

@@ -1246,7 +1249,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12461249
offset = 0;
12471250
}
12481251

1249-
iov_iter_advance(iter, size - left);
1252+
iov_iter_revert(iter, left);
12501253
out:
12511254
while (i < nr_pages)
12521255
put_page(pages[i++]);

block/blk-map.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
254254
size_t offs, added = 0;
255255
int npages;
256256

257-
bytes = iov_iter_get_pages_alloc(iter, &pages, LONG_MAX, &offs);
257+
bytes = iov_iter_get_pages_alloc2(iter, &pages, LONG_MAX, &offs);
258258
if (unlikely(bytes <= 0)) {
259259
ret = bytes ? bytes : -EFAULT;
260260
goto out_unmap;
@@ -284,7 +284,6 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
284284
bytes -= n;
285285
offs = 0;
286286
}
287-
iov_iter_advance(iter, added);
288287
}
289288
/*
290289
* release the pages we didn't map into the bio, if any
@@ -293,8 +292,10 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
293292
put_page(pages[j++]);
294293
kvfree(pages);
295294
/* couldn't stuff something into bio? */
296-
if (bytes)
295+
if (bytes) {
296+
iov_iter_revert(iter, bytes);
297297
break;
298+
}
298299
}
299300

300301
ret = blk_rq_append_bio(rq, bio);

block/fops.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb,
7575

7676
if (iov_iter_rw(iter) == READ) {
7777
bio_init(&bio, bdev, vecs, nr_pages, REQ_OP_READ);
78-
if (iter_is_iovec(iter))
78+
if (user_backed_iter(iter))
7979
should_dirty = true;
8080
} else {
8181
bio_init(&bio, bdev, vecs, nr_pages, dio_bio_write_op(iocb));
@@ -204,7 +204,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
204204
}
205205

206206
dio->size = 0;
207-
if (is_read && iter_is_iovec(iter))
207+
if (is_read && user_backed_iter(iter))
208208
dio->flags |= DIO_SHOULD_DIRTY;
209209

210210
blk_start_plug(&plug);
@@ -335,7 +335,7 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
335335
dio->size = bio->bi_iter.bi_size;
336336

337337
if (is_read) {
338-
if (iter_is_iovec(iter)) {
338+
if (user_backed_iter(iter)) {
339339
dio->flags |= DIO_SHOULD_DIRTY;
340340
bio_set_pages_dirty(bio);
341341
}

crypto/af_alg.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len)
404404
ssize_t n;
405405
int npages, i;
406406

407-
n = iov_iter_get_pages(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
407+
n = iov_iter_get_pages2(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
408408
if (n < 0)
409409
return n;
410410

@@ -1191,7 +1191,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
11911191
len += err;
11921192
atomic_add(err, &ctx->rcvused);
11931193
rsgl->sg_num_bytes = err;
1194-
iov_iter_advance(&msg->msg_iter, err);
11951194
}
11961195

11971196
*outlen = len;

crypto/algif_hash.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,12 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
102102
err = crypto_wait_req(crypto_ahash_update(&ctx->req),
103103
&ctx->wait);
104104
af_alg_free_sg(&ctx->sgl);
105-
if (err)
105+
if (err) {
106+
iov_iter_revert(&msg->msg_iter, len);
106107
goto unlock;
108+
}
107109

108110
copied += len;
109-
iov_iter_advance(&msg->msg_iter, len);
110111
}
111112

112113
err = 0;

drivers/vhost/scsi.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,14 +643,12 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
643643
size_t offset;
644644
unsigned int npages = 0;
645645

646-
bytes = iov_iter_get_pages(iter, pages, LONG_MAX,
646+
bytes = iov_iter_get_pages2(iter, pages, LONG_MAX,
647647
VHOST_SCSI_PREALLOC_UPAGES, &offset);
648648
/* No pages were pinned */
649649
if (bytes <= 0)
650650
return bytes < 0 ? bytes : -EFAULT;
651651

652-
iov_iter_advance(iter, bytes);
653-
654652
while (bytes) {
655653
unsigned n = min_t(unsigned, PAGE_SIZE - offset, bytes);
656654
sg_set_page(sg++, pages[npages++], n, offset);

fs/ceph/addr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
329329

330330
dout("%s: pos=%llu orig_len=%zu len=%llu\n", __func__, subreq->start, subreq->len, len);
331331
iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, subreq->start, len);
332-
err = iov_iter_get_pages_alloc(&iter, &pages, len, &page_off);
332+
err = iov_iter_get_pages_alloc2(&iter, &pages, len, &page_off);
333333
if (err < 0) {
334334
dout("%s: iov_ter_get_pages_alloc returned %d\n", __func__, err);
335335
goto out;

fs/ceph/file.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ static ssize_t __iter_get_bvecs(struct iov_iter *iter, size_t maxsize,
9595
size_t start;
9696
int idx = 0;
9797

98-
bytes = iov_iter_get_pages(iter, pages, maxsize - size,
98+
bytes = iov_iter_get_pages2(iter, pages, maxsize - size,
9999
ITER_GET_BVECS_PAGES, &start);
100100
if (bytes < 0)
101101
return size ?: bytes;
102102

103-
iov_iter_advance(iter, bytes);
104103
size += bytes;
105104

106105
for ( ; bytes; idx++, bvec_idx++) {
@@ -1262,7 +1261,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
12621261
size_t count = iov_iter_count(iter);
12631262
loff_t pos = iocb->ki_pos;
12641263
bool write = iov_iter_rw(iter) == WRITE;
1265-
bool should_dirty = !write && iter_is_iovec(iter);
1264+
bool should_dirty = !write && user_backed_iter(iter);
12661265

12671266
if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
12681267
return -EROFS;

fs/cifs/file.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3276,7 +3276,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
32763276
if (ctx->direct_io) {
32773277
ssize_t result;
32783278

3279-
result = iov_iter_get_pages_alloc(
3279+
result = iov_iter_get_pages_alloc2(
32803280
from, &pagevec, cur_len, &start);
32813281
if (result < 0) {
32823282
cifs_dbg(VFS,
@@ -3290,7 +3290,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
32903290
break;
32913291
}
32923292
cur_len = (size_t)result;
3293-
iov_iter_advance(from, cur_len);
32943293

32953294
nr_pages =
32963295
(cur_len + start + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -4012,7 +4011,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
40124011
if (ctx->direct_io) {
40134012
ssize_t result;
40144013

4015-
result = iov_iter_get_pages_alloc(
4014+
result = iov_iter_get_pages_alloc2(
40164015
&direct_iov, &pagevec,
40174016
cur_len, &start);
40184017
if (result < 0) {
@@ -4028,7 +4027,6 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
40284027
break;
40294028
}
40304029
cur_len = (size_t)result;
4031-
iov_iter_advance(&direct_iov, cur_len);
40324030

40334031
rdata = cifs_readdata_direct_alloc(
40344032
pagevec, cifs_uncached_readv_complete);
@@ -4258,7 +4256,7 @@ static ssize_t __cifs_readv(
42584256
if (!is_sync_kiocb(iocb))
42594257
ctx->iocb = iocb;
42604258

4261-
if (iter_is_iovec(to))
4259+
if (user_backed_iter(to))
42624260
ctx->should_dirty = true;
42634261

42644262
if (direct) {

fs/cifs/misc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
10221022
saved_len = count;
10231023

10241024
while (count && npages < max_pages) {
1025-
rc = iov_iter_get_pages(iter, pages, count, max_pages, &start);
1025+
rc = iov_iter_get_pages2(iter, pages, count, max_pages, &start);
10261026
if (rc < 0) {
10271027
cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
10281028
break;
@@ -1034,7 +1034,6 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
10341034
break;
10351035
}
10361036

1037-
iov_iter_advance(iter, rc);
10381037
count -= rc;
10391038
rc += start;
10401039
cur_npages = DIV_ROUND_UP(rc, PAGE_SIZE);

0 commit comments

Comments
 (0)