Loading fs/io_uring.c +28 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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[] = { Loading Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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) Loading @@ -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 Loading
fs/io_uring.c +28 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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[] = { Loading Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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) Loading @@ -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