We don't need a separate member in io_rw for this, we can just use the kiocb->private field as we're not using it for anything else anyway. This saves 8 bytes in io_rw, which we'll be needing once kiocb grows a new member. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- fs/io_uring.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 91a301bb1644..f35b54f016f3 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -557,7 +557,6 @@ struct io_rw { /* NOTE: kiocb has the file as the first member, so don't do it here */ struct kiocb kiocb; u64 addr; - u64 len; }; struct io_connect { @@ -2675,6 +2674,16 @@ static bool io_file_supports_nowait(struct io_kiocb *req, int rw) return __io_file_supports_nowait(req->file, rw); } +static inline void *u64_to_ptr(__u64 ptr) +{ + return (void *)(unsigned long) ptr; +} + +static inline __u64 ptr_to_u64(void *ptr) +{ + return (__u64)(unsigned long)ptr; +} + static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_ring_ctx *ctx = req->ctx; @@ -2732,7 +2741,7 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe) } req->rw.addr = READ_ONCE(sqe->addr); - req->rw.len = READ_ONCE(sqe->len); + req->rw.kiocb.private = u64_to_ptr(READ_ONCE(sqe->len)); req->buf_index = READ_ONCE(sqe->buf_index); return 0; } @@ -2799,7 +2808,7 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, static int __io_import_fixed(struct io_kiocb *req, int rw, struct iov_iter *iter, struct io_mapped_ubuf *imu) { - size_t len = req->rw.len; + size_t len = ptr_to_u64(req->rw.kiocb.private); u64 buf_end, buf_addr = req->rw.addr; size_t offset; @@ -2997,7 +3006,7 @@ static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov, iov[0].iov_len = kbuf->len; return 0; } - if (req->rw.len != 1) + if (ptr_to_u64(req->rw.kiocb.private) != 1) return -EINVAL; #ifdef CONFIG_COMPAT @@ -3012,7 +3021,7 @@ static int io_import_iovec(int rw, struct io_kiocb *req, struct iovec **iovec, struct iov_iter *iter, bool needs_lock) { void __user *buf = u64_to_user_ptr(req->rw.addr); - size_t sqe_len = req->rw.len; + size_t sqe_len = ptr_to_u64(req->rw.kiocb.private); u8 opcode = req->opcode; ssize_t ret; @@ -3030,7 +3039,7 @@ static int io_import_iovec(int rw, struct io_kiocb *req, struct iovec **iovec, buf = io_rw_buffer_select(req, &sqe_len, needs_lock); if (IS_ERR(buf)) return PTR_ERR(buf); - req->rw.len = sqe_len; + req->rw.kiocb.private = u64_to_ptr(sqe_len); } ret = import_single_range(rw, buf, sqe_len, *iovec, iter); @@ -3063,6 +3072,7 @@ static ssize_t loop_rw_iter(int rw, struct io_kiocb *req, struct iov_iter *iter) { struct kiocb *kiocb = &req->rw.kiocb; struct file *file = req->file; + unsigned long rw_len; ssize_t ret = 0; /* @@ -3075,6 +3085,7 @@ static ssize_t loop_rw_iter(int rw, struct io_kiocb *req, struct iov_iter *iter) if (kiocb->ki_flags & IOCB_NOWAIT) return -EAGAIN; + rw_len = ptr_to_u64(req->rw.kiocb.private); while (iov_iter_count(iter)) { struct iovec iovec; ssize_t nr; @@ -3083,7 +3094,7 @@ static ssize_t loop_rw_iter(int rw, struct io_kiocb *req, struct iov_iter *iter) iovec = iov_iter_iovec(iter); } else { iovec.iov_base = u64_to_user_ptr(req->rw.addr); - iovec.iov_len = req->rw.len; + iovec.iov_len = rw_len; } if (rw == READ) { @@ -3102,7 +3113,7 @@ static ssize_t loop_rw_iter(int rw, struct io_kiocb *req, struct iov_iter *iter) ret += nr; if (nr != iovec.iov_len) break; - req->rw.len -= nr; + rw_len -= nr; req->rw.addr += nr; iov_iter_advance(iter, nr); } -- 2.32.0