* [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