This provides consistency between io_uring and the respective I/O syscall and avoids having the user of liburing specify the cwd in sqe for IORING_OP_UNLINKAT. Signed-off-by: Usama Arif <usama.arif@xxxxxxxxxxxxx> --- fs/io_uring.c | 22 ++++++++++++++++------ include/uapi/linux/io_uring.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 8bf56523ff7f..d38c5f54f6a4 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1308,6 +1308,7 @@ static const struct io_op_def io_op_defs[] = { }, [IORING_OP_RENAME] = {}, [IORING_OP_RENAMEAT] = {}, + [IORING_OP_UNLINK] = {}, [IORING_OP_UNLINKAT] = {}, [IORING_OP_MKDIRAT] = {}, [IORING_OP_SYMLINKAT] = {}, @@ -1454,6 +1455,8 @@ const char *io_uring_get_opcode(u8 opcode) return "RENAME"; case IORING_OP_RENAMEAT: return "RENAMEAT"; + case IORING_OP_UNLINK: + return "UNLINK"; case IORING_OP_UNLINKAT: return "UNLINKAT"; case IORING_OP_MKDIRAT: @@ -4847,8 +4850,8 @@ static int io_setxattr(struct io_kiocb *req, unsigned int issue_flags) return 0; } -static int io_unlinkat_prep(struct io_kiocb *req, - const struct io_uring_sqe *sqe) +static int io_unlink_prep(struct io_kiocb *req, + const struct io_uring_sqe *sqe, bool is_cwd) { struct io_unlink *un = &req->unlink; const char __user *fname; @@ -4858,7 +4861,10 @@ static int io_unlinkat_prep(struct io_kiocb *req, if (unlikely(req->flags & REQ_F_FIXED_FILE)) return -EBADF; - un->dfd = READ_ONCE(sqe->fd); + if (is_cwd) + un->dfd = AT_FDCWD; + else + un->dfd = READ_ONCE(sqe->fd); un->flags = READ_ONCE(sqe->unlink_flags); if (un->flags & ~AT_REMOVEDIR) @@ -4873,7 +4879,7 @@ static int io_unlinkat_prep(struct io_kiocb *req, return 0; } -static int io_unlinkat(struct io_kiocb *req, unsigned int issue_flags) +static int io_unlink(struct io_kiocb *req, unsigned int issue_flags) { struct io_unlink *un = &req->unlink; int ret; @@ -8087,8 +8093,10 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) return io_rename_prep(req, sqe, 1); case IORING_OP_RENAMEAT: return io_rename_prep(req, sqe, 0); + case IORING_OP_UNLINK: + return io_unlink_prep(req, sqe, 1); case IORING_OP_UNLINKAT: - return io_unlinkat_prep(req, sqe); + return io_unlink_prep(req, sqe, 0); case IORING_OP_MKDIRAT: return io_mkdirat_prep(req, sqe); case IORING_OP_SYMLINKAT: @@ -8243,6 +8251,7 @@ static void io_clean_op(struct io_kiocb *req) putname(req->rename.oldpath); putname(req->rename.newpath); break; + case IORING_OP_UNLINK: case IORING_OP_UNLINKAT: putname(req->unlink.filename); break; @@ -8409,8 +8418,9 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags) case IORING_OP_RENAMEAT: ret = io_rename(req, issue_flags); break; + case IORING_OP_UNLINK: case IORING_OP_UNLINKAT: - ret = io_unlinkat(req, issue_flags); + ret = io_unlink(req, issue_flags); break; case IORING_OP_MKDIRAT: ret = io_mkdirat(req, issue_flags); diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 73f4e1c4133d..7828b7183d01 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -190,6 +190,7 @@ enum io_uring_op { IORING_OP_SOCKET, IORING_OP_URING_CMD, IORING_OP_RENAME, + IORING_OP_UNLINK, /* this goes last, obviously */ IORING_OP_LAST, -- 2.25.1