* Re: [PATCH v3 4/5] io_uring: add fsetxattr and setxattr support
@ 2021-12-04 13:56 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2021-12-04 13:56 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 16866 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20211203191516.1327214-5-shr@fb.com>
References: <20211203191516.1327214-5-shr@fb.com>
TO: Stefan Roesch <shr@fb.com>
TO: io-uring(a)vger.kernel.org
TO: linux-fsdevel(a)vger.kernel.org
TO: kernel-team(a)fb.com
CC: shr(a)fb.com
Hi Stefan,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on c2b8fe96d041238d18228b8384e094cc959497ed]
url: https://github.com/0day-ci/linux/commits/Stefan-Roesch/io_uring-add-xattr-support/20211204-031657
base: c2b8fe96d041238d18228b8384e094cc959497ed
:::::: branch date: 19 hours ago
:::::: commit date: 19 hours ago
config: mips-randconfig-c004-20211203 (https://download.01.org/0day-ci/archive/20211204/202112042139.bHHzzWrL-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d30fcadf07ee552f20156ea90be2fdb54cb9cb08)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install mips cross compiling tool for clang build
# apt-get install binutils-mips-linux-gnu
# https://github.com/0day-ci/linux/commit/6d1076ace03a9946908f906508f9fe32043b81c1
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stefan-Roesch/io_uring-add-xattr-support/20211204-031657
git checkout 6d1076ace03a9946908f906508f9fe32043b81c1
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=mips clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
^~~~~~~~~~~~~~~~~~~~~~
include/linux/fault-inject-usercopy.h:18:49: note: Returning zero, which participates in a condition later
static inline bool should_fail_usercopy(void) { return false; }
^~~~~~~~~~~~
include/linux/uaccess.h:157:7: note: Returning from 'should_fail_usercopy'
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
^~~~~~~~~~~~~~~~~~~~~~
include/linux/uaccess.h:157:6: note: Left side of '&&' is true
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
^
include/linux/uaccess.h:157:40: note: Assuming the condition is false
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
^
arch/mips/include/asm/uaccess.h:88:2: note: expanded from macro 'access_ok'
likely(__access_ok((addr), (size)))
^
include/linux/compiler.h:45:22: note: expanded from macro 'likely'
# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x)))
^
include/linux/compiler.h:33:32: note: expanded from macro '__branch_check__'
______r = __builtin_expect(!!(x), expect); \
^
include/linux/compiler.h:45:39: note: expanded from macro 'likely'
# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x)))
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler.h:33:34: note: expanded from macro '__branch_check__'
______r = __builtin_expect(!!(x), expect); \
^
include/linux/uaccess.h:157:40: note: Assuming the condition is false
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
^
arch/mips/include/asm/uaccess.h:88:2: note: expanded from macro 'access_ok'
likely(__access_ok((addr), (size)))
^
include/linux/compiler.h:45:22: note: expanded from macro 'likely'
# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x)))
^
include/linux/compiler.h:33:32: note: expanded from macro '__branch_check__'
______r = __builtin_expect(!!(x), expect); \
^
include/linux/compiler.h:45:66: note: expanded from macro 'likely'
# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x)))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
include/linux/compiler.h:35:19: note: expanded from macro '__branch_check__'
expect, is_constant); \
^~~~~~~~~~~
include/linux/uaccess.h:157:2: note: Taking true branch
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
^
include/linux/uaccess.h:159:9: note: Calling 'raw_copy_from_user'
res = raw_copy_from_user(to, from, n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/mips/include/asm/uaccess.h:455:2: note: Returning without writing to '*to'
return __cu_len_r;
^
include/linux/uaccess.h:159:9: note: Returning from 'raw_copy_from_user'
res = raw_copy_from_user(to, from, n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/uaccess.h:161:6: note: Assuming 'res' is 0, which participates in a condition later
if (unlikely(res))
^
include/linux/compiler.h:48:24: note: expanded from macro 'unlikely'
# define unlikely(x) (__branch_check__(x, 0, __builtin_constant_p(x)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/compiler.h:33:32: note: expanded from macro '__branch_check__'
______r = __builtin_expect(!!(x), expect); \
^~~~
include/linux/uaccess.h:161:2: note: Taking false branch
if (unlikely(res))
^
include/linux/uaccess.h:163:2: note: Returning without writing to '*to'
return res;
^
include/linux/uaccess.h:163:2: note: Returning zero (loaded from 'res'), which participates in a condition later
return res;
^~~~~~~~~~
include/linux/uaccess.h:192:7: note: Returning from '_copy_from_user'
n = _copy_from_user(to, from, n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/uaccess.h:193:2: note: Returning without writing to '*to'
return n;
^
include/linux/uaccess.h:193:2: note: Returning zero (loaded from 'n'), which participates in a condition later
return n;
^~~~~~~~
fs/io_uring.c:11017:6: note: Returning from 'copy_from_user'
if (copy_from_user(new_count, arg, sizeof(new_count)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/io_uring.c:11017:2: note: Taking false branch
if (copy_from_user(new_count, arg, sizeof(new_count)))
^
fs/io_uring.c:11019:7: note: The value 0 is assigned to 'i'
for (i = 0; i < ARRAY_SIZE(new_count); i++)
^~~~~
fs/io_uring.c:11019:2: note: Loop condition is true. Entering loop body
for (i = 0; i < ARRAY_SIZE(new_count); i++)
^
fs/io_uring.c:11020:20: note: The left operand of '>' is a garbage value
if (new_count[i] > INT_MAX)
~~~~~~~~~~~~ ^
>> include/linux/fs.h:2725:21: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
return mnt_user_ns(file->f_path.mnt);
^
fs/io_uring.c:7331:25: note: Left side of '||' is true
req->opcode = opcode = READ_ONCE(sqe->opcode);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:302:29: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
fs/io_uring.c:7331:25: note: Taking false branch
req->opcode = opcode = READ_ONCE(sqe->opcode);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:2: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:335:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:323:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:315:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
fs/io_uring.c:7331:25: note: Loop condition is false. Exiting loop
req->opcode = opcode = READ_ONCE(sqe->opcode);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:2: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:335:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:323:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:307:2: note: expanded from macro '__compiletime_assert'
do { \
^
fs/io_uring.c:7333:27: note: Left side of '||' is true
req->flags = sqe_flags = READ_ONCE(sqe->flags);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:302:29: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
fs/io_uring.c:7333:27: note: Taking false branch
req->flags = sqe_flags = READ_ONCE(sqe->flags);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:2: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:335:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:323:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:315:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
fs/io_uring.c:7333:27: note: Loop condition is false. Exiting loop
req->flags = sqe_flags = READ_ONCE(sqe->flags);
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:2: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:335:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:323:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:307:2: note: expanded from macro '__compiletime_assert'
do { \
^
fs/io_uring.c:7334:19: note: Left side of '||' is false
req->user_data = READ_ONCE(sqe->user_data);
vim +2725 include/linux/fs.h
^1da177e4c3f41 Linus Torvalds 2005-04-16 2722
a6435940b62f81 Christian Brauner 2021-01-21 2723 static inline struct user_namespace *file_mnt_user_ns(struct file *file)
a6435940b62f81 Christian Brauner 2021-01-21 2724 {
a6435940b62f81 Christian Brauner 2021-01-21 @2725 return mnt_user_ns(file->f_path.mnt);
a6435940b62f81 Christian Brauner 2021-01-21 2726 }
7df818b2370a9a Al Viro 2016-03-25 2727 extern long vfs_truncate(const struct path *, loff_t);
643fe55a0679ae Christian Brauner 2021-01-21 2728 int do_truncate(struct user_namespace *, struct dentry *, loff_t start,
643fe55a0679ae Christian Brauner 2021-01-21 2729 unsigned int time_attrs, struct file *filp);
72c72bdf7bf533 Anna Schumaker 2014-11-07 2730 extern int vfs_fallocate(struct file *file, int mode, loff_t offset,
3e63cbb1efca7d Ankit Jain 2009-06-19 2731 loff_t len);
8e8a1407ac23b4 Jason Uhlenkott 2007-10-20 2732 extern long do_sys_open(int dfd, const char __user *filename, int flags,
a218d0fdc5f900 Al Viro 2011-11-21 2733 umode_t mode);
669abf4e5539c8 Jeff Layton 2012-10-10 2734 extern struct file *file_open_name(struct filename *, int, umode_t);
a218d0fdc5f900 Al Viro 2011-11-21 2735 extern struct file *filp_open(const char *, int, umode_t);
ffb37ca3bd16ce Al Viro 2021-04-01 2736 extern struct file *file_open_root(const struct path *,
378c6520e7d292 Jann Horn 2016-03-22 2737 const char *, int, umode_t);
ffb37ca3bd16ce Al Viro 2021-04-01 2738 static inline struct file *file_open_root_mnt(struct vfsmount *mnt,
ffb37ca3bd16ce Al Viro 2021-04-01 2739 const char *name, int flags, umode_t mode)
ffb37ca3bd16ce Al Viro 2021-04-01 2740 {
ffb37ca3bd16ce Al Viro 2021-04-01 2741 return file_open_root(&(struct path){.mnt = mnt, .dentry = mnt->mnt_root},
ffb37ca3bd16ce Al Viro 2021-04-01 2742 name, flags, mode);
ffb37ca3bd16ce Al Viro 2021-04-01 2743 }
765927b2d50871 Al Viro 2012-06-26 2744 extern struct file * dentry_open(const struct path *, int, const struct cred *);
2abc77af89e175 Al Viro 2018-07-12 2745 extern struct file * open_with_fake_path(const struct path *, int,
2abc77af89e175 Al Viro 2018-07-12 2746 struct inode*, const struct cred *);
19f391eb05b8b0 Al Viro 2018-06-08 2747 static inline struct file *file_clone_open(struct file *file)
19f391eb05b8b0 Al Viro 2018-06-08 2748 {
19f391eb05b8b0 Al Viro 2018-06-08 2749 return dentry_open(&file->f_path, file->f_flags, file->f_cred);
19f391eb05b8b0 Al Viro 2018-06-08 2750 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2751 extern int filp_close(struct file *, fl_owner_t id);
91a27b2a756784 Jeff Layton 2012-10-10 2752
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH v3 0/5] io_uring: add xattr support
@ 2021-12-03 19:15 Stefan Roesch
2021-12-03 19:15 ` [PATCH v3 4/5] io_uring: add fsetxattr and setxattr support Stefan Roesch
0 siblings, 1 reply; 2+ messages in thread
From: Stefan Roesch @ 2021-12-03 19:15 UTC (permalink / raw)
To: io-uring, linux-fsdevel, kernel-team; +Cc: shr
This adds the xattr support to io_uring. The intent is to have a more
complete support for file operations in io_uring.
This change adds support for the following functions to io_uring:
- fgetxattr
- fsetxattr
- getxattr
- setxattr
Patch 1: fs: split off do_user_path_at_empty from user_path_at_empty()
This splits off a new function do_user_path_at_empty from
user_path_at_empty that is based on filename and not on a
user-specified string.
Patch 2: fs: split off setxattr_setup function from setxattr
Split off the setup part of the setxattr function.
Patch 3: fs: split off do_getxattr from getxattr
Split of the do_getxattr part from getxattr. This will
allow it to be invoked it from io_uring.
Patch 4: io_uring: add fsetxattr and setxattr support
This adds new functions to support the fsetxattr and setxattr
functions.
Patch 5: io_uring: add fgetxattr and getxattr support
This adds new functions to support the fgetxattr and getxattr
functions.
There are two additional patches:
liburing: Add support for xattr api's.
This also includes the tests for the new code.
xfstests: Add support for io_uring xattr support.
---
V3: - remove req->file checks in prep functions
- change size parameter in do_xattr
V2: - split off function do_user_path_empty instead of changing
the function signature of user_path_at
- Fix datatype size problem in do_getxattr
Stefan Roesch (5):
fs: split off do_user_path_at_empty from user_path_at_empty()
fs: split off setxattr_setup function from setxattr
fs: split off do_getxattr from getxattr
io_uring: add fsetxattr and setxattr support
io_uring: add fgetxattr and getxattr support
fs/internal.h | 23 +++
fs/io_uring.c | 321 ++++++++++++++++++++++++++++++++++
fs/namei.c | 10 +-
fs/xattr.c | 106 +++++++----
include/linux/namei.h | 2 +
include/uapi/linux/io_uring.h | 8 +-
6 files changed, 431 insertions(+), 39 deletions(-)
Signed-off-by: Stefan Roesch <shr@fb.com>
base-commit: c2b8fe96d041238d18228b8384e094cc959497ed
--
2.30.2
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH v3 4/5] io_uring: add fsetxattr and setxattr support
2021-12-03 19:15 [PATCH v3 0/5] io_uring: add xattr support Stefan Roesch
@ 2021-12-03 19:15 ` Stefan Roesch
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Roesch @ 2021-12-03 19:15 UTC (permalink / raw)
To: io-uring, linux-fsdevel, kernel-team; +Cc: shr
This adds support to io_uring for the fsetxattr and setxattr API.
Signed-off-by: Stefan Roesch <shr@fb.com>
---
fs/io_uring.c | 171 ++++++++++++++++++++++++++++++++++
include/uapi/linux/io_uring.h | 6 +-
2 files changed, 176 insertions(+), 1 deletion(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 568729677e25..b8e195472f05 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -81,6 +81,7 @@
#include <linux/tracehook.h>
#include <linux/audit.h>
#include <linux/security.h>
+#include <linux/xattr.h>
#define CREATE_TRACE_POINTS
#include <trace/events/io_uring.h>
@@ -717,6 +718,13 @@ struct io_async_rw {
struct wait_page_queue wpq;
};
+struct io_xattr {
+ struct file *file;
+ struct xattr_ctx ctx;
+ void *value;
+ struct filename *filename;
+};
+
enum {
REQ_F_FIXED_FILE_BIT = IOSQE_FIXED_FILE_BIT,
REQ_F_IO_DRAIN_BIT = IOSQE_IO_DRAIN_BIT,
@@ -856,6 +864,7 @@ struct io_kiocb {
struct io_mkdir mkdir;
struct io_symlink symlink;
struct io_hardlink hardlink;
+ struct io_xattr xattr;
};
u8 opcode;
@@ -1105,6 +1114,10 @@ static const struct io_op_def io_op_defs[] = {
[IORING_OP_MKDIRAT] = {},
[IORING_OP_SYMLINKAT] = {},
[IORING_OP_LINKAT] = {},
+ [IORING_OP_FSETXATTR] = {
+ .needs_file = 1
+ },
+ [IORING_OP_SETXATTR] = {},
};
/* requests with any of those set should undergo io_disarm_next() */
@@ -3818,6 +3831,144 @@ static int io_renameat(struct io_kiocb *req, unsigned int issue_flags)
return 0;
}
+static int __io_setxattr_prep(struct io_kiocb *req,
+ const struct io_uring_sqe *sqe,
+ struct user_namespace *user_ns)
+{
+ struct io_xattr *ix = &req->xattr;
+ const char __user *name;
+ void *ret;
+
+ if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
+ return -EINVAL;
+ if (unlikely(sqe->ioprio))
+ return -EINVAL;
+ if (unlikely(req->flags & REQ_F_FIXED_FILE))
+ return -EBADF;
+
+ ix->filename = NULL;
+ name = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ 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);
+
+ ix->ctx.kname = kmalloc(XATTR_NAME_MAX + 1, GFP_KERNEL);
+ if (!ix->ctx.kname)
+ return -ENOMEM;
+ ix->ctx.kname_sz = XATTR_NAME_MAX + 1;
+
+ ret = setxattr_setup(user_ns, name, &ix->ctx);
+ if (IS_ERR(ret)) {
+ kfree(ix->ctx.kname);
+ return PTR_ERR(ret);
+ }
+
+ ix->value = ret;
+ req->flags |= REQ_F_NEED_CLEANUP;
+ return 0;
+}
+
+static int io_setxattr_prep(struct io_kiocb *req,
+ const struct io_uring_sqe *sqe)
+{
+ struct io_xattr *ix = &req->xattr;
+ const char __user *path;
+ int ret;
+
+ ret = __io_setxattr_prep(req, sqe, current_user_ns());
+ if (ret)
+ return ret;
+
+ path = u64_to_user_ptr(READ_ONCE(sqe->addr3));
+
+ ix->filename = getname_flags(path, LOOKUP_FOLLOW, NULL);
+ if (IS_ERR(ix->filename)) {
+ ret = PTR_ERR(ix->filename);
+ ix->filename = NULL;
+ }
+
+ return ret;
+}
+
+static int io_fsetxattr_prep(struct io_kiocb *req,
+ const struct io_uring_sqe *sqe)
+{
+ return __io_setxattr_prep(req, sqe, file_mnt_user_ns(req->file));
+}
+
+static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags,
+ struct path *path)
+{
+ struct io_xattr *ix = &req->xattr;
+ int ret;
+
+ ret = mnt_want_write(path->mnt);
+ if (!ret) {
+ ret = vfs_setxattr(mnt_user_ns(path->mnt), path->dentry,
+ ix->ctx.kname, ix->value, ix->ctx.size,
+ ix->ctx.flags);
+ mnt_drop_write(path->mnt);
+ }
+
+ return ret;
+}
+
+static int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_xattr *ix = &req->xattr;
+ int ret;
+
+ if (issue_flags & IO_URING_F_NONBLOCK)
+ return -EAGAIN;
+
+ ret = __io_setxattr(req, issue_flags, &req->file->f_path);
+
+ req->flags &= ~REQ_F_NEED_CLEANUP;
+ kfree(ix->ctx.kname);
+
+ if (ix->value)
+ kvfree(ix->value);
+ if (ret < 0)
+ req_set_fail(req);
+
+ io_req_complete(req, ret);
+ return 0;
+}
+
+static int io_setxattr(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_xattr *ix = &req->xattr;
+ unsigned int lookup_flags = LOOKUP_FOLLOW;
+ struct path path;
+ int ret;
+
+ if (issue_flags & IO_URING_F_NONBLOCK)
+ return -EAGAIN;
+
+retry:
+ ret = do_user_path_at_empty(AT_FDCWD, ix->filename, lookup_flags, &path);
+ putname(ix->filename);
+ if (!ret) {
+ ret = __io_setxattr(req, issue_flags, &path);
+ path_put(&path);
+ if (retry_estale(ret, lookup_flags)) {
+ lookup_flags |= LOOKUP_REVAL;
+ goto retry;
+ }
+ }
+
+ req->flags &= ~REQ_F_NEED_CLEANUP;
+ kfree(ix->ctx.kname);
+
+ if (ix->value)
+ kvfree(ix->value);
+ if (ret < 0)
+ req_set_fail(req);
+
+ io_req_complete(req, ret);
+ return 0;
+}
+
static int io_unlinkat_prep(struct io_kiocb *req,
const struct io_uring_sqe *sqe)
{
@@ -6531,6 +6682,10 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return io_symlinkat_prep(req, sqe);
case IORING_OP_LINKAT:
return io_linkat_prep(req, sqe);
+ case IORING_OP_FSETXATTR:
+ return io_fsetxattr_prep(req, sqe);
+ case IORING_OP_SETXATTR:
+ return io_setxattr_prep(req, sqe);
}
printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
@@ -6674,6 +6829,15 @@ static void io_clean_op(struct io_kiocb *req)
putname(req->hardlink.oldpath);
putname(req->hardlink.newpath);
break;
+ case IORING_OP_SETXATTR:
+ if (req->xattr.filename)
+ putname(req->xattr.filename);
+ fallthrough;
+ case IORING_OP_FSETXATTR:
+ kfree(req->xattr.ctx.kname);
+ if (req->xattr.value)
+ kvfree(req->xattr.value);
+ break;
}
}
if ((req->flags & REQ_F_POLLED) && req->apoll) {
@@ -6816,6 +6980,12 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
case IORING_OP_LINKAT:
ret = io_linkat(req, issue_flags);
break;
+ case IORING_OP_FSETXATTR:
+ ret = io_fsetxattr(req, issue_flags);
+ break;
+ case IORING_OP_SETXATTR:
+ ret = io_setxattr(req, issue_flags);
+ break;
default:
ret = -EINVAL;
break;
@@ -11183,6 +11353,7 @@ static int __init io_uring_init(void)
BUILD_BUG_SQE_ELEM(42, __u16, personality);
BUILD_BUG_SQE_ELEM(44, __s32, splice_fd_in);
BUILD_BUG_SQE_ELEM(44, __u32, file_index);
+ BUILD_BUG_SQE_ELEM(48, __u64, addr3);
BUILD_BUG_ON(sizeof(struct io_uring_files_update) !=
sizeof(struct io_uring_rsrc_update));
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 787f491f0d2a..dbf473900da2 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -45,6 +45,7 @@ struct io_uring_sqe {
__u32 rename_flags;
__u32 unlink_flags;
__u32 hardlink_flags;
+ __u32 xattr_flags;
};
__u64 user_data; /* data to be passed back at completion time */
/* pack this to avoid bogus arm OABI complaints */
@@ -60,7 +61,8 @@ struct io_uring_sqe {
__s32 splice_fd_in;
__u32 file_index;
};
- __u64 __pad2[2];
+ __u64 addr3;
+ __u64 __pad2[1];
};
enum {
@@ -143,6 +145,8 @@ enum {
IORING_OP_MKDIRAT,
IORING_OP_SYMLINKAT,
IORING_OP_LINKAT,
+ IORING_OP_FSETXATTR,
+ IORING_OP_SETXATTR,
/* this goes last, obviously */
IORING_OP_LAST,
--
2.30.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-12-04 13:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-04 13:56 [PATCH v3 4/5] io_uring: add fsetxattr and setxattr support kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2021-12-03 19:15 [PATCH v3 0/5] io_uring: add xattr support Stefan Roesch
2021-12-03 19:15 ` [PATCH v3 4/5] io_uring: add fsetxattr and setxattr support Stefan Roesch
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.