Skip to content

Commit

Permalink
io_uring: grab ->fs as part of async preparation
Browse files Browse the repository at this point in the history
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: [email protected] # 5.3+
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Feb 8, 2020
1 parent 9392a27 commit ff002b3
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include <linux/fsnotify.h>
#include <linux/fadvise.h>
#include <linux/eventpoll.h>
#include <linux/fs_struct.h>

#define CREATE_TRACE_POINTS
#include <trace/events/io_uring.h>
Expand Down Expand Up @@ -611,6 +612,8 @@ struct io_op_def {
unsigned not_supported : 1;
/* needs file table */
unsigned file_table : 1;
/* needs ->fs */
unsigned needs_fs : 1;
};

static const struct io_op_def io_op_defs[] = {
Expand Down Expand Up @@ -653,12 +656,14 @@ static const struct io_op_def io_op_defs[] = {
.needs_mm = 1,
.needs_file = 1,
.unbound_nonreg_file = 1,
.needs_fs = 1,
},
[IORING_OP_RECVMSG] = {
.async_ctx = 1,
.needs_mm = 1,
.needs_file = 1,
.unbound_nonreg_file = 1,
.needs_fs = 1,
},
[IORING_OP_TIMEOUT] = {
.async_ctx = 1,
Expand Down Expand Up @@ -689,6 +694,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_file = 1,
.fd_non_neg = 1,
.file_table = 1,
.needs_fs = 1,
},
[IORING_OP_CLOSE] = {
.needs_file = 1,
Expand All @@ -702,6 +708,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_mm = 1,
.needs_file = 1,
.fd_non_neg = 1,
.needs_fs = 1,
},
[IORING_OP_READ] = {
.needs_mm = 1,
Expand Down Expand Up @@ -733,6 +740,7 @@ static const struct io_op_def io_op_defs[] = {
.needs_file = 1,
.fd_non_neg = 1,
.file_table = 1,
.needs_fs = 1,
},
[IORING_OP_EPOLL_CTL] = {
.unbound_nonreg_file = 1,
Expand Down Expand Up @@ -907,6 +915,16 @@ static inline void io_req_work_grab_env(struct io_kiocb *req,
}
if (!req->work.creds)
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)
Expand All @@ -919,6 +937,16 @@ static inline void io_req_work_drop_env(struct io_kiocb *req)
put_cred(req->work.creds);
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,
Expand Down

0 comments on commit ff002b3

Please sign in to comment.