From: Gabriel Krisman Bertazi <krisman@suse.de>
To: Aditya Prakash Srivastava <aditya.ansh182@gmail.com>,
Jens Axboe <axboe@kernel.dk>,
Christian Brauner <brauner@kernel.org>,
Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jan Kara <jack@suse.cz>,
io-uring@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org,
Aditya Prakash Srivastava <aditya.ansh182@gmail.com>
Subject: Re: [PATCH v3 2/2] io_uring: add fremovexattr and flistxattr support
Date: Fri, 14 Aug 2026 12:39:57 -0400 [thread overview]
Message-ID: <87v79c4pwi.fsf@mailhost.krisman.be> (raw)
In-Reply-To: <20260721103514.2716-3-aditya.ansh182@gmail.com>
Aditya Prakash Srivastava <aditya.ansh182@gmail.com> writes:
> Add support for IORING_OP_FREMOVEXATTR and IORING_OP_FLISTXATTR. This
> enables xattr listing and removal operations to be executed in an
> asynchronous fashion.
>
> Signed-off-by: Aditya Prakash Srivastava <aditya.ansh182@gmail.com>
Jens has made a point about avoiding new commands just punting to the wq
at [1].[1] https://github.com/axboe/liburing/issues/1492#issuecomment-4683773809
In this case, we have an immediate issue for inline submission with
acquiring the mount and the inode lock and there is no callbacks so we
are not really in good shape to work around it. Beyond that...
> ---
> include/uapi/linux/io_uring.h | 2 +
> io_uring/opdef.c | 18 +++++++
> io_uring/xattr.c | 74 +++++++++++++++++++++++++++++
> io_uring/xattr.h | 6 +++
> tools/include/uapi/linux/io_uring.h | 13 +++++
> 5 files changed, 113 insertions(+)
>
> diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
> index 909fb7aea638..805f1e31f492 100644
> --- a/include/uapi/linux/io_uring.h
> +++ b/include/uapi/linux/io_uring.h
> @@ -318,6 +318,8 @@ enum io_uring_op {
> IORING_OP_PIPE,
> IORING_OP_NOP128,
> IORING_OP_URING_CMD128,
> + IORING_OP_FREMOVEXATTR,
> + IORING_OP_FLISTXATTR,
>
> /* this goes last, obviously */
> IORING_OP_LAST,
> diff --git a/io_uring/opdef.c b/io_uring/opdef.c
> index 4e58eb1344ea..25d9229d8fc0 100644
> --- a/io_uring/opdef.c
> +++ b/io_uring/opdef.c
> @@ -591,6 +591,16 @@ const struct io_issue_def io_issue_defs[] = {
> .prep = io_uring_cmd_prep,
> .issue = io_uring_cmd,
> },
> + [IORING_OP_FREMOVEXATTR] = {
> + .needs_file = 1,
> + .prep = io_fremovexattr_prep,
> + .issue = io_fremovexattr,
> + },
> + [IORING_OP_FLISTXATTR] = {
> + .needs_file = 1,
> + .prep = io_flistxattr_prep,
> + .issue = io_flistxattr,
> + },
> };
>
> const struct io_cold_def io_cold_defs[] = {
> @@ -849,6 +859,14 @@ const struct io_cold_def io_cold_defs[] = {
> .sqe_copy = io_uring_cmd_sqe_copy,
> .cleanup = io_uring_cmd_cleanup,
> },
> + [IORING_OP_FREMOVEXATTR] = {
> + .name = "FREMOVEXATTR",
> + .cleanup = io_xattr_cleanup,
> + },
> + [IORING_OP_FLISTXATTR] = {
> + .name = "FLISTXATTR",
> + .cleanup = io_xattr_cleanup,
> + },
> };
>
> const char *io_uring_get_opcode(u8 opcode)
> diff --git a/io_uring/xattr.c b/io_uring/xattr.c
> index 5303df3f247f..9b410f91ef43 100644
> --- a/io_uring/xattr.c
> +++ b/io_uring/xattr.c
> @@ -195,3 +195,77 @@ int io_setxattr(struct io_kiocb *req, unsigned int issue_flags)
> io_xattr_finish(req, ret);
> return IOU_COMPLETE;
> }
> +
> +int io_fremovexattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
> +{
> + struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
> + const char __user *name;
> + int ret;
> +
> + INIT_DELAYED_FILENAME(&ix->filename);
> + name = u64_to_user_ptr(READ_ONCE(sqe->addr));
> +
> + if (READ_ONCE(sqe->addr2) || READ_ONCE(sqe->len) || READ_ONCE(sqe->xattr_flags))
> + return -EINVAL;
There are more fields to be rejected here, check the latest patches from
Yi Xie such as cc609376e9a4 ("io_uring/fs: check unused sqe fields for
unlinkat").
> +
> + ix->ctx.kname = kmalloc_obj(*ix->ctx.kname);
> + if (!ix->ctx.kname)
> + return -ENOMEM;
> +
> + ret = import_xattr_name(ix->ctx.kname, name);
> + if (ret) {
> + kfree(ix->ctx.kname);
> + return ret;
> + }
> +
> + req->flags |= REQ_F_NEED_CLEANUP;
> + req->flags |= REQ_F_FORCE_ASYNC;
This will cause the cleanup to call io_xattr_cleanup, which does kfree
on ix->ctx.kvalue, which is never initialized. If it has garbage from a
previous command in the kiocb cmd space, you can craft a corruption or,
more likely, a crash.
> + return 0;
> +}
> +
> +int io_fremovexattr(struct io_kiocb *req, unsigned int issue_flags)
> +{
> + struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
> + int ret;
> +
> + WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
> +
> + ret = file_removexattr(req->file, ix->ctx.kname);
> + io_xattr_finish(req, ret);
> + return IOU_COMPLETE;
> +}
> +
> +int io_flistxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
> +{
> + struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
> +
> + INIT_DELAYED_FILENAME(&ix->filename);
> + ix->ctx.kname = NULL;
> + ix->ctx.kvalue = NULL;
> +
> + if (READ_ONCE(sqe->addr))
> + return -EINVAL;
> +
> + ix->ctx.value = u64_to_user_ptr(READ_ONCE(sqe->addr2));
> + ix->ctx.size = READ_ONCE(sqe->len);
> + ix->ctx.flags = READ_ONCE(sqe->xattr_flags);
> +
> + if (ix->ctx.flags)
> + return -EINVAL;
> +
> + req->flags |= REQ_F_NEED_CLEANUP;
> + req->flags |= REQ_F_FORCE_ASYNC;
> + return 0;
> +}
> +
> +int io_flistxattr(struct io_kiocb *req, unsigned int issue_flags)
> +{
> + struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
> + int ret;
> +
> + WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
> +
> + ret = file_listxattr(req->file, ix->ctx.value, ix->ctx.size);
> + io_xattr_finish(req, ret);
> + return IOU_COMPLETE;
> +}
> diff --git a/io_uring/xattr.h b/io_uring/xattr.h
> index 9b459d2ae90c..d2487b49a5d2 100644
> --- a/io_uring/xattr.h
> +++ b/io_uring/xattr.h
> @@ -13,3 +13,9 @@ int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags);
>
> int io_getxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
> int io_getxattr(struct io_kiocb *req, unsigned int issue_flags);
> +
> +int io_fremovexattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
> +int io_fremovexattr(struct io_kiocb *req, unsigned int issue_flags);
> +
> +int io_flistxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
> +int io_flistxattr(struct io_kiocb *req, unsigned int issue_flags);
> diff --git a/tools/include/uapi/linux/io_uring.h b/tools/include/uapi/linux/io_uring.h
> index f1c16f817742..79bf7c22009d 100644
> --- a/tools/include/uapi/linux/io_uring.h
> +++ b/tools/include/uapi/linux/io_uring.h
> @@ -253,6 +253,19 @@ enum io_uring_op {
> IORING_OP_FUTEX_WAIT,
> IORING_OP_FUTEX_WAKE,
> IORING_OP_FUTEX_WAITV,
> + IORING_OP_FIXED_FD_INSTALL,
> + IORING_OP_FTRUNCATE,
> + IORING_OP_BIND,
> + IORING_OP_LISTEN,
> + IORING_OP_RECV_ZC,
> + IORING_OP_EPOLL_WAIT,
> + IORING_OP_READV_FIXED,
> + IORING_OP_WRITEV_FIXED,
> + IORING_OP_PIPE,
> + IORING_OP_NOP128,
> + IORING_OP_URING_CMD128,
> + IORING_OP_FREMOVEXATTR,
> + IORING_OP_FLISTXATTR,
I'd rather these (minus the xattr ones) go in a separate fix patch ahead of
the series...
--
Gabriel Krisman Bertazi
prev parent reply other threads:[~2026-08-14 16:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 10:35 [PATCH v3 0/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
2026-07-21 10:35 ` [PATCH v3 1/2] fs: make file_listxattr and file_removexattr helpers non-static Aditya Prakash Srivastava
2026-07-27 14:46 ` Jan Kara
2026-07-21 10:35 ` [PATCH v3 2/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
2026-08-13 16:22 ` Aditya Prakash Srivastava
2026-08-14 16:39 ` Gabriel Krisman Bertazi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v79c4pwi.fsf@mailhost.krisman.be \
--to=krisman@suse.de \
--cc=aditya.ansh182@gmail.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=io-uring@vger.kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.