Commit 7b7699c0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull iov_iter fixes from Al Viro:
 "Fixes for io-uring handling of iov_iter reexpands"

* 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  io_uring: reexpand under-reexpanded iters
  iov_iter: track truncated size
parents 70868a18 89c2b3b7
...@@ -3480,6 +3480,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) ...@@ -3480,6 +3480,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
if (req->flags & REQ_F_NOWAIT) if (req->flags & REQ_F_NOWAIT)
goto done; goto done;
/* some cases will consume bytes even on error returns */ /* some cases will consume bytes even on error returns */
iov_iter_reexpand(iter, iter->count + iter->truncated);
iov_iter_revert(iter, io_size - iov_iter_count(iter)); iov_iter_revert(iter, io_size - iov_iter_count(iter));
ret = 0; ret = 0;
} else if (ret == -EIOCBQUEUED) { } else if (ret == -EIOCBQUEUED) {
...@@ -3619,6 +3620,7 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) ...@@ -3619,6 +3620,7 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags)
} else { } else {
copy_iov: copy_iov:
/* some cases will consume bytes even on error returns */ /* some cases will consume bytes even on error returns */
iov_iter_reexpand(iter, iter->count + iter->truncated);
iov_iter_revert(iter, io_size - iov_iter_count(iter)); iov_iter_revert(iter, io_size - iov_iter_count(iter));
ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
return ret ?: -EAGAIN; return ret ?: -EAGAIN;
......
...@@ -47,6 +47,7 @@ struct iov_iter { ...@@ -47,6 +47,7 @@ struct iov_iter {
}; };
loff_t xarray_start; loff_t xarray_start;
}; };
size_t truncated;
}; };
static inline enum iter_type iov_iter_type(const struct iov_iter *i) static inline enum iter_type iov_iter_type(const struct iov_iter *i)
...@@ -254,8 +255,10 @@ static inline void iov_iter_truncate(struct iov_iter *i, u64 count) ...@@ -254,8 +255,10 @@ static inline void iov_iter_truncate(struct iov_iter *i, u64 count)
* conversion in assignement is by definition greater than all * conversion in assignement is by definition greater than all
* values of size_t, including old i->count. * values of size_t, including old i->count.
*/ */
if (i->count > count) if (i->count > count) {
i->truncated += i->count - count;
i->count = count; i->count = count;
}
} }
/* /*
...@@ -264,6 +267,7 @@ static inline void iov_iter_truncate(struct iov_iter *i, u64 count) ...@@ -264,6 +267,7 @@ static inline void iov_iter_truncate(struct iov_iter *i, u64 count)
*/ */
static inline void iov_iter_reexpand(struct iov_iter *i, size_t count) static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
{ {
i->truncated -= count - i->count;
i->count = count; i->count = count;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment