mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 05:20:53 +07:00
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: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
9392a27d88
commit
ff002b3018
@ -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>
|
||||
@ -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[] = {
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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(¤t->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(¤t->fs->lock);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user