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