summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2022-06-06 23:44:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2022-07-06 16:23:32 -0400
commit18fa9af7263164ec9a8d7b28a848324825f14672 (patch)
treed721e63bee57d4ac1080e7fa437db0409963ff8c /lib
parent59bb69c67cf1475a04cd5629d9c4f6dbbcba5e4a (diff)
iov_iter_bvec_advance(): don't bother with bvec_iter
do what we do for iovec/kvec; that ends up generating better code, AFAICS. Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib')
-rw-r--r--lib/iov_iter.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 4c658a25e29c..c51314639615 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -846,17 +846,22 @@ static void pipe_advance(struct iov_iter *i, size_t size)
static void iov_iter_bvec_advance(struct iov_iter *i, size_t size)
{
- struct bvec_iter bi;
+ const struct bio_vec *bvec, *end;
- bi.bi_size = i->count;
- bi.bi_bvec_done = i->iov_offset;
- bi.bi_idx = 0;
- bvec_iter_advance(i->bvec, &bi, size);
+ if (!i->count)
+ return;
+ i->count -= size;
+
+ size += i->iov_offset;
- i->bvec += bi.bi_idx;
- i->nr_segs -= bi.bi_idx;
- i->count = bi.bi_size;
- i->iov_offset = bi.bi_bvec_done;
+ for (bvec = i->bvec, end = bvec + i->nr_segs; bvec < end; bvec++) {
+ if (likely(size < bvec->bv_len))
+ break;
+ size -= bvec->bv_len;
+ }
+ i->iov_offset = size;
+ i->nr_segs -= bvec - i->bvec;
+ i->bvec = bvec;
}
static void iov_iter_iovec_advance(struct iov_iter *i, size_t size)