public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] io_uring: add fremovexattr and flistxattr support
@ 2026-07-21  8:54 Aditya Prakash Srivastava
  2026-07-21  8:54 ` [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static Aditya Prakash Srivastava
  2026-07-21  8:54 ` [PATCH v2 2/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
  0 siblings, 2 replies; 4+ messages in thread
From: Aditya Prakash Srivastava @ 2026-07-21  8:54 UTC (permalink / raw)
  To: Jens Axboe, Christian Brauner, Alexander Viro
  Cc: Jan Kara, io-uring, linux-fsdevel, linux-kernel,
	Aditya Prakash Srivastava

This series completes io_uring's FD-based xattr operations by adding
support for:
- IORING_OP_FREMOVEXATTR
- IORING_OP_FLISTXATTR

This allows asynchronous xattr removal and listing. Support is restricted
to FD-based operations on registered files to avoid path lookup overhead.

Corresponding test suite modifications have been integrated into the
official liburing test suite (test/xattr.c) and verified to pass
successfully. A corresponding liburing patch implementing these prep
helpers, sanitizers, and test cases is following this kernel series.

- Patch 1 makes the necessary VFS-layer list/remove helpers non-static
  and declares them in fs/internal.h.
- Patch 2 implements the io_uring operational support (opcodes, opdefs,
  preparation, and issue handlers) and invokes these exposed helpers.

Changes since v1:
- Omit path-based opcodes to prioritize optimal FD-based variants.
- Limit exported VFS helpers to only file_listxattr and file_removexattr.
- Rewrite standalone test program into a standard liburing testcase.

Aditya Prakash Srivastava (2):
  fs: make file_listxattr and file_removexattr helpers non-static
  io_uring: add fremovexattr and flistxattr support

 fs/internal.h                       |  2 +
 fs/xattr.c                          | 10 ++--
 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 +++++
 7 files changed, 119 insertions(+), 6 deletions(-)

-- 
2.47.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static
  2026-07-21  8:54 [PATCH v2 0/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
@ 2026-07-21  8:54 ` Aditya Prakash Srivastava
  2026-07-21 10:24   ` Aditya Prakash Srivastava
  2026-07-21  8:54 ` [PATCH v2 2/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
  1 sibling, 1 reply; 4+ messages in thread
From: Aditya Prakash Srivastava @ 2026-07-21  8:54 UTC (permalink / raw)
  To: Jens Axboe, Christian Brauner, Alexander Viro
  Cc: Jan Kara, io-uring, linux-fsdevel, linux-kernel,
	Aditya Prakash Srivastava

In preparation for adding IORING_OP_FREMOVEXATTR and
IORING_OP_FLISTXATTR support in io_uring, we need to invoke the VFS-layer
helpers from within io_uring.

Make the following helpers non-static and declare them in fs/internal.h:
- file_listxattr()
- file_removexattr()

No functional change is introduced.

Signed-off-by: Aditya Prakash Srivastava <aditya.ansh182@gmail.com>
---
 fs/internal.h |  2 ++
 fs/xattr.c    | 10 ++++------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 355d93f92208..ee86b24db79a 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -297,6 +297,8 @@ int filename_setxattr(int dfd, struct filename *filename,
 		      unsigned int lookup_flags, struct kernel_xattr_ctx *ctx);
 int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx);
 int import_xattr_name(struct xattr_name *kname, const char __user *name);
+ssize_t file_listxattr(struct file *f, char __user *list, size_t size);
+int file_removexattr(struct file *f, struct xattr_name *kname);
 
 int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);
 
diff --git a/fs/xattr.c b/fs/xattr.c
index d58979115200..a3a7241846c3 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -953,17 +953,15 @@ listxattr(struct dentry *d, char __user *list, size_t size)
 	return error;
 }
 
-static
 ssize_t file_listxattr(struct file *f, char __user *list, size_t size)
 {
 	audit_file(f);
 	return listxattr(f->f_path.dentry, list, size);
 }
 
-static
-ssize_t filename_listxattr(int dfd, struct filename *filename,
-			   unsigned int lookup_flags,
-			   char __user *list, size_t size)
+static ssize_t filename_listxattr(int dfd, struct filename *filename,
+				  unsigned int lookup_flags,
+				  char __user *list, size_t size)
 {
 	struct path path;
 	ssize_t error;
@@ -1036,7 +1034,7 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d, const char *name)
 	return vfs_removexattr(idmap, d, name);
 }
 
-static int file_removexattr(struct file *f, struct xattr_name *kname)
+int file_removexattr(struct file *f, struct xattr_name *kname)
 {
 	int error = mnt_want_write_file(f);
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] io_uring: add fremovexattr and flistxattr support
  2026-07-21  8:54 [PATCH v2 0/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
  2026-07-21  8:54 ` [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static Aditya Prakash Srivastava
@ 2026-07-21  8:54 ` Aditya Prakash Srivastava
  1 sibling, 0 replies; 4+ messages in thread
From: Aditya Prakash Srivastava @ 2026-07-21  8:54 UTC (permalink / raw)
  To: Jens Axboe, Christian Brauner, Alexander Viro
  Cc: Jan Kara, io-uring, linux-fsdevel, linux-kernel,
	Aditya Prakash Srivastava

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>
---
 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;
+
+	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;
+	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,
 
 	/* this goes last, obviously */
 	IORING_OP_LAST,
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static
  2026-07-21  8:54 ` [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static Aditya Prakash Srivastava
@ 2026-07-21 10:24   ` Aditya Prakash Srivastava
  0 siblings, 0 replies; 4+ messages in thread
From: Aditya Prakash Srivastava @ 2026-07-21 10:24 UTC (permalink / raw)
  To: Jens Axboe, Christian Brauner, Alexander Viro
  Cc: Jan Kara, io-uring, linux-fsdevel, linux-kernel

On Tue, Jul 21, 2026 at 2:25 PM Aditya Prakash Srivastava
<aditya.ansh182@gmail.com> wrote:

> -static
> -ssize_t filename_listxattr(int dfd, struct filename *filename,
> -                          unsigned int lookup_flags,
> -                          char __user *list, size_t size)
> +static ssize_t filename_listxattr(int dfd, struct filename *filename,
> +                                 unsigned int lookup_flags,
> +                                 char __user *list, size_t size)

Please ignore this patch series as it has some redundant changes on
top of v1, sorry about the noise. Will send a v3 by removing the
redundant change.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-21 10:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21  8:54 [PATCH v2 0/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava
2026-07-21  8:54 ` [PATCH v2 1/2] fs: make file_listxattr and file_removexattr helpers non-static Aditya Prakash Srivastava
2026-07-21 10:24   ` Aditya Prakash Srivastava
2026-07-21  8:54 ` [PATCH v2 2/2] io_uring: add fremovexattr and flistxattr support Aditya Prakash Srivastava

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox