@@ -262,6 +262,7 @@ enum io_uring_op {
IORING_OP_FTRUNCATE,
IORING_OP_BIND,
IORING_OP_LISTEN,
+ IORING_OP_FCHMOD,
/* this goes last, obviously */
IORING_OP_LAST,
@@ -47,6 +47,11 @@ struct io_link {
int flags;
};
+struct io_fchmod {
+ struct file *file;
+ umode_t mode;
+};
+
int io_renameat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) {
struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename); @@ -291,3 +296,30 @@ void io_link_cleanup(struct io_kiocb *req)
putname(sl->oldpath);
putname(sl->newpath);
}
+
+int io_fchmod_prep(struct io_kiocb *req, const struct io_uring_sqe
+*sqe) {
+ struct io_fchmod *fc = io_kiocb_to_cmd(req, struct io_fchmod);
+
+ if (unlikely(sqe->off || sqe->addr || sqe->rw_flags ||
+ sqe->buf_index || sqe->splice_fd_in))
+ return -EINVAL;
+ if (unlikely(req->flags & REQ_F_FIXED_FILE))
+ return -EBADF;
+
+ fc->mode = READ_ONCE(sqe->len);
+ req->flags |= REQ_F_FORCE_ASYNC;
+ return 0;
+}
+
+int io_fchmod(struct io_kiocb *req, unsigned int issue_flags) {
+ struct io_fchmod *fc = io_kiocb_to_cmd(req, struct io_fchmod);
+ int ret;
+
+ WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
+
+ ret = vfs_fchmod(req->file, fc->mode);
+ io_req_set_res(req, ret, 0);
+ return IOU_OK;
+}
@@ -18,3 +18,6 @@ int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags); int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); int io_linkat(struct io_kiocb *req, unsigned int issue_flags); void io_link_cleanup(struct io_kiocb *req);
+
+int io_fchmod_prep(struct io_kiocb *req, const struct io_uring_sqe
+*sqe); int io_fchmod(struct io_kiocb *req, unsigned int issue_flags);
@@ -515,6 +515,11 @@ const struct io_issue_def io_issue_defs[] = {
Adds support for doing chmod through io_uring. IORING_OP_FCHMOD behaves like fchmod(2) and takes the same arguments. Signed-off-by: Li Zetao <lizetao1@huawei.com> --- include/uapi/linux/io_uring.h | 1 + io_uring/fs.c | 32 ++++++++++++++++++++++++++++++++ io_uring/fs.h | 3 +++ io_uring/opdef.c | 8 ++++++++ 4 files changed, 44 insertions(+) .prep = io_eopnotsupp_prep, #endif }, + [IORING_OP_FCHMOD] = { + .needs_file = 1, + .prep = io_fchmod_prep, + .issue = io_fchmod, + }, }; const struct io_cold_def io_cold_defs[] = { @@ -744,6 +749,9 @@ const struct io_cold_def io_cold_defs[] = { [IORING_OP_LISTEN] = { .name = "LISTEN", }, + [IORING_OP_FCHMOD] = { + .name = "FCHMOD", + }, }; const char *io_uring_get_opcode(u8 opcode) -- 2.34.1