@@ -749,15 +749,14 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
return -EOPNOTSUPP;
while (iov_iter_count(iter)) {
- struct iovec iovec = iov_iter_iovec(iter);
ssize_t nr;
if (type == READ) {
- nr = filp->f_op->read(filp, iovec.iov_base,
- iovec.iov_len, ppos);
+ nr = filp->f_op->read(filp, iter_iov_addr(iter),
+ iter_iov_len(iter), ppos);
} else {
- nr = filp->f_op->write(filp, iovec.iov_base,
- iovec.iov_len, ppos);
+ nr = filp->f_op->write(filp, iter_iov_addr(iter),
+ iter_iov_len(iter), ppos);
}
if (nr < 0) {
@@ -766,7 +765,7 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
break;
}
ret += nr;
- if (nr != iovec.iov_len)
+ if (nr != iter_iov_len(iter))
break;
iov_iter_advance(iter, nr);
}
@@ -70,6 +70,8 @@ struct iov_iter {
};
#define iter_iov(iter) (iter)->__iov
+#define iter_iov_addr(iter) (iter_iov(iter)->iov_base + (iter)->iov_offset)
+#define iter_iov_len(iter) (iter_iov(iter)->iov_len - (iter)->iov_offset)
static inline enum iter_type iov_iter_type(const struct iov_iter *i)
{
@@ -447,26 +447,25 @@ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter)
ppos = io_kiocb_ppos(kiocb);
while (iov_iter_count(iter)) {
- struct iovec iovec;
+ void __user *addr;
+ size_t len;
ssize_t nr;
if (iter_is_ubuf(iter)) {
- iovec.iov_base = iter->ubuf + iter->iov_offset;
- iovec.iov_len = iov_iter_count(iter);
+ addr = iter->ubuf + iter->iov_offset;
+ len = iov_iter_count(iter);
} else if (!iov_iter_is_bvec(iter)) {
- iovec = iov_iter_iovec(iter);
+ addr = iter_iov_addr(iter);
+ len = iter_iov_len(iter);
} else {
- iovec.iov_base = u64_to_user_ptr(rw->addr);
- iovec.iov_len = rw->len;
+ addr = u64_to_user_ptr(rw->addr);
+ len = rw->len;
}
- if (ddir == READ) {
- nr = file->f_op->read(file, iovec.iov_base,
- iovec.iov_len, ppos);
- } else {
- nr = file->f_op->write(file, iovec.iov_base,
- iovec.iov_len, ppos);
- }
+ if (ddir == READ)
+ nr = file->f_op->read(file, addr, len, ppos);
+ else
+ nr = file->f_op->write(file, addr, len, ppos);
if (nr < 0) {
if (!ret)
@@ -482,7 +481,7 @@ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter)
if (!rw->len)
break;
}
- if (nr != iovec.iov_len)
+ if (nr != len)
break;
}
@@ -1456,7 +1456,7 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
size_t, vlen, int, behavior, unsigned int, flags)
{
ssize_t ret;
- struct iovec iovstack[UIO_FASTIOV], iovec;
+ struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov = iovstack;
struct iov_iter iter;
struct task_struct *task;
@@ -1503,12 +1503,11 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec,
total_len = iov_iter_count(&iter);
while (iov_iter_count(&iter)) {
- iovec = iov_iter_iovec(&iter);
- ret = do_madvise(mm, (unsigned long)iovec.iov_base,
- iovec.iov_len, behavior);
+ ret = do_madvise(mm, (unsigned long)iter_iov_addr(&iter),
+ iter_iov_len(&iter), behavior);
if (ret < 0)
break;
- iov_iter_advance(&iter, iovec.iov_len);
+ iov_iter_advance(&iter, iter_iov_len(&iter));
}
ret = (total_len - iov_iter_count(&iter)) ? : ret;
These just return the address and length of the current iovec segment in the iterator. Convert existing iov_iter_iovec() users to use them instead of getting a copy of the current vec. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- fs/read_write.c | 11 +++++------ include/linux/uio.h | 2 ++ io_uring/rw.c | 27 +++++++++++++-------------- mm/madvise.c | 9 ++++----- 4 files changed, 24 insertions(+), 25 deletions(-)