Commit ff002b30 authored by Jens Axboe's avatar Jens Axboe

io_uring: grab ->fs as part of async preparation

This passes it in to io-wq, so it assumes the right fs_struct when
executing async work that may need to do lookups.

Cc: stable@vger.kernel.org # 5.3+
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9392a27d
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include <linux/fsnotify.h> #include <linux/fsnotify.h>
#include <linux/fadvise.h> #include <linux/fadvise.h>
#include <linux/eventpoll.h> #include <linux/eventpoll.h>
#include <linux/fs_struct.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/io_uring.h> #include <trace/events/io_uring.h>
...@@ -611,6 +612,8 @@ struct io_op_def { ...@@ -611,6 +612,8 @@ struct io_op_def {
unsigned not_supported : 1; unsigned not_supported : 1;
/* needs file table */ /* needs file table */
unsigned file_table : 1; unsigned file_table : 1;
/* needs ->fs */
unsigned needs_fs : 1;
}; };
static const struct io_op_def io_op_defs[] = { static const struct io_op_def io_op_defs[] = {
...@@ -653,12 +656,14 @@ static const struct io_op_def io_op_defs[] = { ...@@ -653,12 +656,14 @@ static const struct io_op_def io_op_defs[] = {
.needs_mm = 1, .needs_mm = 1,
.needs_file = 1, .needs_file = 1,
.unbound_nonreg_file = 1, .unbound_nonreg_file = 1,
.needs_fs = 1,
}, },
[IORING_OP_RECVMSG] = { [IORING_OP_RECVMSG] = {
.async_ctx = 1, .async_ctx = 1,
.needs_mm = 1, .needs_mm = 1,
.needs_file = 1, .needs_file = 1,
.unbound_nonreg_file = 1, .unbound_nonreg_file = 1,
.needs_fs = 1,
}, },
[IORING_OP_TIMEOUT] = { [IORING_OP_TIMEOUT] = {
.async_ctx = 1, .async_ctx = 1,
...@@ -689,6 +694,7 @@ static const struct io_op_def io_op_defs[] = { ...@@ -689,6 +694,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_file = 1, .needs_file = 1,
.fd_non_neg = 1, .fd_non_neg = 1,
.file_table = 1, .file_table = 1,
.needs_fs = 1,
}, },
[IORING_OP_CLOSE] = { [IORING_OP_CLOSE] = {
.needs_file = 1, .needs_file = 1,
...@@ -702,6 +708,7 @@ static const struct io_op_def io_op_defs[] = { ...@@ -702,6 +708,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_mm = 1, .needs_mm = 1,
.needs_file = 1, .needs_file = 1,
.fd_non_neg = 1, .fd_non_neg = 1,
.needs_fs = 1,
}, },
[IORING_OP_READ] = { [IORING_OP_READ] = {
.needs_mm = 1, .needs_mm = 1,
...@@ -733,6 +740,7 @@ static const struct io_op_def io_op_defs[] = { ...@@ -733,6 +740,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_file = 1, .needs_file = 1,
.fd_non_neg = 1, .fd_non_neg = 1,
.file_table = 1, .file_table = 1,
.needs_fs = 1,
}, },
[IORING_OP_EPOLL_CTL] = { [IORING_OP_EPOLL_CTL] = {
.unbound_nonreg_file = 1, .unbound_nonreg_file = 1,
...@@ -907,6 +915,16 @@ static inline void io_req_work_grab_env(struct io_kiocb *req, ...@@ -907,6 +915,16 @@ static inline void io_req_work_grab_env(struct io_kiocb *req,
} }
if (!req->work.creds) if (!req->work.creds)
req->work.creds = get_current_cred(); req->work.creds = get_current_cred();
if (!req->work.fs && def->needs_fs) {
spin_lock(&current->fs->lock);
if (!current->fs->in_exec) {
req->work.fs = current->fs;
req->work.fs->users++;
} else {
req->work.flags |= IO_WQ_WORK_CANCEL;
}
spin_unlock(&current->fs->lock);
}
} }
static inline void io_req_work_drop_env(struct io_kiocb *req) static inline void io_req_work_drop_env(struct io_kiocb *req)
...@@ -919,6 +937,16 @@ static inline void io_req_work_drop_env(struct io_kiocb *req) ...@@ -919,6 +937,16 @@ static inline void io_req_work_drop_env(struct io_kiocb *req)
put_cred(req->work.creds); put_cred(req->work.creds);
req->work.creds = NULL; req->work.creds = NULL;
} }
if (req->work.fs) {
struct fs_struct *fs = req->work.fs;
spin_lock(&req->work.fs->lock);
if (--fs->users)
fs = NULL;
spin_unlock(&req->work.fs->lock);
if (fs)
free_fs_struct(fs);
}
} }
static inline bool io_prep_async_work(struct io_kiocb *req, static inline bool io_prep_async_work(struct io_kiocb *req,
......
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