diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-21 16:29:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-21 16:29:24 -0700 |
commit | b080cee72ef355669cbc52ff55dc513d37433600 (patch) | |
tree | cef571297dc9cd08042a8f5ecd2484ae837cd389 /fs/io_uring.c | |
parent | af472a9efdf65cbb3398cb6478ec0e89fbc84109 (diff) | |
parent | 1b6fe6e0dfecf8c82a64fb87148ad9333fa2f62e (diff) | |
download | linux-b080cee72ef355669cbc52ff55dc513d37433600.tar.bz2 |
Merge tag 'for-5.18/io_uring-statx-2022-03-18' of git://git.kernel.dk/linux-block
Pull io_uring statx fixes from Jens Axboe:
"On top of the main io_uring branch, this is to ensure that the
filename component of statx is stable after submit.
That requires a few VFS related changes"
* tag 'for-5.18/io_uring-statx-2022-03-18' of git://git.kernel.dk/linux-block:
io-uring: Make statx API stable
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 5fa736344b67..496a2af7d12c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -675,7 +675,7 @@ struct io_statx { int dfd; unsigned int mask; unsigned int flags; - const char __user *filename; + struct filename *filename; struct statx __user *buffer; }; @@ -5000,6 +5000,8 @@ static int io_fadvise(struct io_kiocb *req, unsigned int issue_flags) static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { + const char __user *path; + if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in) @@ -5009,10 +5011,22 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) req->statx.dfd = READ_ONCE(sqe->fd); req->statx.mask = READ_ONCE(sqe->len); - req->statx.filename = u64_to_user_ptr(READ_ONCE(sqe->addr)); + path = u64_to_user_ptr(READ_ONCE(sqe->addr)); req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2)); req->statx.flags = READ_ONCE(sqe->statx_flags); + req->statx.filename = getname_flags(path, + getname_statx_lookup_flags(req->statx.flags), + NULL); + + if (IS_ERR(req->statx.filename)) { + int ret = PTR_ERR(req->statx.filename); + + req->statx.filename = NULL; + return ret; + } + + req->flags |= REQ_F_NEED_CLEANUP; return 0; } @@ -7112,6 +7126,10 @@ static void io_clean_op(struct io_kiocb *req) putname(req->hardlink.oldpath); putname(req->hardlink.newpath); break; + case IORING_OP_STATX: + if (req->statx.filename) + putname(req->statx.filename); + break; } } if ((req->flags & REQ_F_POLLED) && req->apoll) { |