* [RFC PATCH 0/2] introduce io_uring_cmd_import_fixed_vec @ 2025-03-11 11:40 Sidong Yang 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang 2025-03-11 11:40 ` [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED Sidong Yang 0 siblings, 2 replies; 10+ messages in thread From: Sidong Yang @ 2025-03-11 11:40 UTC (permalink / raw) To: Jens Axboe, Pavel Begunkov, Josef Bacik, David Sterba Cc: Sidong Yang, io-uring, linux-kernel, linux-btrfs This patche series introduce io_uring_cmd_import_vec. With this function, Multiple fixed buffer could be used in uring cmd. It's vectored version for io_uring_cmd_import_fixed(). Also this patch series includes a usage for new api for encoded read in btrfs by using uring cmd. Sidong Yang (2): io_uring: cmd: introduce io_uring_cmd_import_fixed_vec btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED fs/btrfs/ioctl.c | 26 +++++++++++++++++++++----- include/linux/io_uring/cmd.h | 14 ++++++++++++++ io_uring/uring_cmd.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) --- Recently, I've found that io_import_reg_vec() was added for io-uring. I think it could be used for io-uring cmd. I've tested for btrfs encoded read and it works. But it seems that there is no performance improvements and I'll keep find why. If there is no need to use fixed buffer for btrfs, I think it's good to use for nvme. 2.43.0 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec 2025-03-11 11:40 [RFC PATCH 0/2] introduce io_uring_cmd_import_fixed_vec Sidong Yang @ 2025-03-11 11:40 ` Sidong Yang 2025-03-11 13:08 ` Pavel Begunkov ` (2 more replies) 2025-03-11 11:40 ` [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED Sidong Yang 1 sibling, 3 replies; 10+ messages in thread From: Sidong Yang @ 2025-03-11 11:40 UTC (permalink / raw) To: Jens Axboe, Pavel Begunkov, Josef Bacik, David Sterba Cc: Sidong Yang, io-uring, linux-kernel, linux-btrfs io_uring_cmd_import_fixed_vec() could be used for using multiple fixed buffer in uring_cmd callback. Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> --- include/linux/io_uring/cmd.h | 14 ++++++++++++++ io_uring/uring_cmd.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 598cacda4aa3..75cf25c1e730 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -44,6 +44,13 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct io_uring_cmd *ioucmd, unsigned int issue_flags); +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, + unsigned long nr_segs, int rw, + struct iov_iter *iter, + struct io_uring_cmd *ioucmd, + struct iou_vec *iou_vec, bool compat, + unsigned int issue_flags); + /* * Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd * and the corresponding io_uring request. @@ -76,6 +83,13 @@ io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, { return -EOPNOTSUPP; } +int io_uring_cmd_import_fixed_vec(int rw, struct iov_iter *iter, + struct io_uring_cmd *ioucmd, + struct iou_vec *vec, unsigned nr_iovs, + unsigned iovec_off, unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, u64 ret2, unsigned issue_flags) { diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index de39b602aa82..58e2932f29e7 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -255,6 +255,35 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, } EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed); +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, + unsigned long nr_segs, int rw, + struct iov_iter *iter, + struct io_uring_cmd *ioucmd, + struct iou_vec *iou_vec, bool compat, + unsigned int issue_flags) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + struct iovec *iov; + int ret; + + iov = iovec_from_user(uiovec, nr_segs, 0, NULL, compat); + if (IS_ERR(iov)) + return PTR_ERR(iov); + + ret = io_vec_realloc(iou_vec, nr_segs); + if (ret) { + kfree(iov); + return ret; + } + memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); + kfree(iov); + + ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, + issue_flags); + return ret; +} +EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); + void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd) { struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang @ 2025-03-11 13:08 ` Pavel Begunkov 2025-03-12 3:08 ` Sidong Yang 2025-03-12 9:59 ` kernel test robot 2025-03-12 10:10 ` kernel test robot 2 siblings, 1 reply; 10+ messages in thread From: Pavel Begunkov @ 2025-03-11 13:08 UTC (permalink / raw) To: Sidong Yang, Jens Axboe, Josef Bacik, David Sterba Cc: io-uring, linux-kernel, linux-btrfs On 3/11/25 11:40, Sidong Yang wrote: > io_uring_cmd_import_fixed_vec() could be used for using multiple > fixed buffer in uring_cmd callback. > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > --- > include/linux/io_uring/cmd.h | 14 ++++++++++++++ > io_uring/uring_cmd.c | 29 +++++++++++++++++++++++++++++ > 2 files changed, 43 insertions(+) > > diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h > index 598cacda4aa3..75cf25c1e730 100644 > --- a/include/linux/io_uring/cmd.h > +++ b/include/linux/io_uring/cmd.h > @@ -44,6 +44,13 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > struct io_uring_cmd *ioucmd, > unsigned int issue_flags); > > +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, > + unsigned long nr_segs, int rw, > + struct iov_iter *iter, > + struct io_uring_cmd *ioucmd, nit: it's better to be the first arg > + struct iou_vec *iou_vec, bool compat, Same comment, iou_vec should not be exposed. And why do we need to pass compat here? Instead of io_is_compat() inside the helper. > + unsigned int issue_flags); > + > /* > * Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd > * and the corresponding io_uring request. > @@ -76,6 +83,13 @@ io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > { > return -EOPNOTSUPP; > } > +int io_uring_cmd_import_fixed_vec(int rw, struct iov_iter *iter, > + struct io_uring_cmd *ioucmd, > + struct iou_vec *vec, unsigned nr_iovs, > + unsigned iovec_off, unsigned int issue_flags) > +{ > + return -EOPNOTSUPP; > +} > static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, > u64 ret2, unsigned issue_flags) > { > diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c > index de39b602aa82..58e2932f29e7 100644 > --- a/io_uring/uring_cmd.c > +++ b/io_uring/uring_cmd.c > @@ -255,6 +255,35 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > } > EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed); > > +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, > + unsigned long nr_segs, int rw, > + struct iov_iter *iter, > + struct io_uring_cmd *ioucmd, > + struct iou_vec *iou_vec, bool compat, > + unsigned int issue_flags) > +{ > + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); > + struct iovec *iov; > + int ret; > + > + iov = iovec_from_user(uiovec, nr_segs, 0, NULL, compat); > + if (IS_ERR(iov)) > + return PTR_ERR(iov); That's one allocation > + > + ret = io_vec_realloc(iou_vec, nr_segs); That's a second one > + if (ret) { > + kfree(iov); > + return ret; > + } > + memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); > + kfree(iov); > + > + ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, It's slightly out of date, the import side should use io_prep_reg_iovec(), it abstracts from iovec placement questions. > + issue_flags); And there will likely be a 3rd one. That's pretty likely why performance is not up to expectations, unlike the rw/net side which cache it to eventually 0 realloctions. The first one can be easily removed, but it'll need better abstractions for cmds not to expose iou_vec. Let me think what would be a good approach here. -- Pavel Begunkov ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec 2025-03-11 13:08 ` Pavel Begunkov @ 2025-03-12 3:08 ` Sidong Yang 0 siblings, 0 replies; 10+ messages in thread From: Sidong Yang @ 2025-03-12 3:08 UTC (permalink / raw) To: Pavel Begunkov Cc: Jens Axboe, Josef Bacik, David Sterba, io-uring, linux-kernel, linux-btrfs On Tue, Mar 11, 2025 at 01:08:14PM +0000, Pavel Begunkov wrote: > On 3/11/25 11:40, Sidong Yang wrote: > > io_uring_cmd_import_fixed_vec() could be used for using multiple > > fixed buffer in uring_cmd callback. > > > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > > --- > > include/linux/io_uring/cmd.h | 14 ++++++++++++++ > > io_uring/uring_cmd.c | 29 +++++++++++++++++++++++++++++ > > 2 files changed, 43 insertions(+) > > > > diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h > > index 598cacda4aa3..75cf25c1e730 100644 > > --- a/include/linux/io_uring/cmd.h > > +++ b/include/linux/io_uring/cmd.h > > @@ -44,6 +44,13 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > > struct io_uring_cmd *ioucmd, > > unsigned int issue_flags); > > +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, > > + unsigned long nr_segs, int rw, > > + struct iov_iter *iter, > > + struct io_uring_cmd *ioucmd, > > nit: it's better to be the first arg Thanks for tip. > > > + struct iou_vec *iou_vec, bool compat, > > Same comment, iou_vec should not be exposed. And why do we > need to pass compat here? Instead of io_is_compat() inside > the helper. Actually I don't know about io_is_compat(). Thanks. > > > + unsigned int issue_flags); > > + > > /* > > * Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd > > * and the corresponding io_uring request. > > @@ -76,6 +83,13 @@ io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > > { > > return -EOPNOTSUPP; > > } > > +int io_uring_cmd_import_fixed_vec(int rw, struct iov_iter *iter, > > + struct io_uring_cmd *ioucmd, > > + struct iou_vec *vec, unsigned nr_iovs, > > + unsigned iovec_off, unsigned int issue_flags) > > +{ > > + return -EOPNOTSUPP; > > +} > > static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, > > u64 ret2, unsigned issue_flags) > > { > > diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c > > index de39b602aa82..58e2932f29e7 100644 > > --- a/io_uring/uring_cmd.c > > +++ b/io_uring/uring_cmd.c > > @@ -255,6 +255,35 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, > > } > > EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed); > > +int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, > > + unsigned long nr_segs, int rw, > > + struct iov_iter *iter, > > + struct io_uring_cmd *ioucmd, > > + struct iou_vec *iou_vec, bool compat, > > + unsigned int issue_flags) > > +{ > > + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); > > + struct iovec *iov; > > + int ret; > > + > > + iov = iovec_from_user(uiovec, nr_segs, 0, NULL, compat); > > + if (IS_ERR(iov)) > > + return PTR_ERR(iov); > > That's one allocation > > > + > > + ret = io_vec_realloc(iou_vec, nr_segs); > > That's a second one > > > + if (ret) { > > + kfree(iov); > > + return ret; > > + } > > + memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); > > + kfree(iov); > > + > > + ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, > > It's slightly out of date, the import side should use io_prep_reg_iovec(), > it abstracts from iovec placement questions. > > > + issue_flags); > > And there will likely be a 3rd one. That's pretty likely why > performance is not up to expectations, unlike the rw/net > side which cache it to eventually 0 realloctions. > > The first one can be easily removed, but it'll need better > abstractions for cmds not to expose iou_vec. Let me think > what would be a good approach here. Totally agreed, There is too many allocation for this. It should be done allocation. Thanks, Sidong > > -- > Pavel Begunkov > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang 2025-03-11 13:08 ` Pavel Begunkov @ 2025-03-12 9:59 ` kernel test robot 2025-03-12 10:10 ` kernel test robot 2 siblings, 0 replies; 10+ messages in thread From: kernel test robot @ 2025-03-12 9:59 UTC (permalink / raw) To: Sidong Yang; +Cc: llvm, oe-kbuild-all Hi Sidong, [This is a private test report for your RFC patch.] kernel test robot noticed the following build warnings: [auto build test WARNING on next-20250307] [also build test WARNING on v6.14-rc6] [cannot apply to kdave/for-next linus/master v6.14-rc6 v6.14-rc5 v6.14-rc4] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sidong-Yang/io_uring-cmd-introduce-io_uring_cmd_import_fixed_vec/20250311-194620 base: next-20250307 patch link: https://lore.kernel.org/r/20250311114053.216359-2-sidong.yang%40furiosa.ai patch subject: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec config: i386-buildonly-randconfig-003-20250312 (https://download.01.org/0day-ci/archive/20250312/202503121708.ZioDSAXU-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250312/202503121708.ZioDSAXU-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503121708.ZioDSAXU-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from io_uring/uring_cmd.c:5: include/linux/io_uring/cmd.h:51:42: warning: 'struct iou_vec' declared inside parameter list will not be visible outside of this definition or declaration 51 | struct iou_vec *iou_vec, bool compat, | ^~~~~~~ >> io_uring/uring_cmd.c:262:42: warning: 'struct iou_vec' declared inside parameter list will not be visible outside of this definition or declaration 262 | struct iou_vec *iou_vec, bool compat, | ^~~~~~~ io_uring/uring_cmd.c:258:5: error: conflicting types for 'io_uring_cmd_import_fixed_vec'; have 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, bool, unsigned int)' {aka 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, _Bool, unsigned int)'} 258 | int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/io_uring/cmd.h:47:5: note: previous declaration of 'io_uring_cmd_import_fixed_vec' with type 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, bool, unsigned int)' {aka 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, _Bool, unsigned int)'} 47 | int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ io_uring/uring_cmd.c: In function 'io_uring_cmd_import_fixed_vec': io_uring/uring_cmd.c:273:15: error: implicit declaration of function 'io_vec_realloc' [-Werror=implicit-function-declaration] 273 | ret = io_vec_realloc(iou_vec, nr_segs); | ^~~~~~~~~~~~~~ In file included from arch/x86/include/asm/string.h:3, from include/linux/string.h:65, from arch/x86/include/asm/page_32.h:18, from arch/x86/include/asm/page.h:14, from arch/x86/include/asm/thread_info.h:12, from include/linux/thread_info.h:60, from include/linux/spinlock.h:60, from include/linux/wait.h:9, from include/linux/wait_bit.h:8, from include/linux/fs.h:7, from include/uapi/linux/io_uring.h:11, from include/linux/io_uring/cmd.h:5: io_uring/uring_cmd.c:278:23: error: invalid use of undefined type 'struct iou_vec' 278 | memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); | ^~ arch/x86/include/asm/string_32.h:150:42: note: in definition of macro 'memcpy' 150 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n) | ^ io_uring/uring_cmd.c:281:15: error: implicit declaration of function 'io_import_reg_vec'; did you mean 'io_import_reg_buf'? [-Werror=implicit-function-declaration] 281 | ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, | ^~~~~~~~~~~~~~~~~ | io_import_reg_buf io_uring/uring_cmd.c:281:64: error: invalid use of undefined type 'struct iou_vec' 281 | ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, | ^~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from io_uring/uring_cmd.c:2: io_uring/uring_cmd.c: At top level: io_uring/uring_cmd.c:285:19: error: conflicting types for 'io_uring_cmd_import_fixed_vec'; have 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, bool, unsigned int)' {aka 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, _Bool, unsigned int)'} 285 | EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/export.h:70:28: note: in definition of macro '__EXPORT_SYMBOL' 70 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:84:41: note: in expansion of macro '_EXPORT_SYMBOL' 84 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ io_uring/uring_cmd.c:285:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 285 | EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); | ^~~~~~~~~~~~~~~~~ include/linux/io_uring/cmd.h:47:5: note: previous declaration of 'io_uring_cmd_import_fixed_vec' with type 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, bool, unsigned int)' {aka 'int(const struct iovec *, long unsigned int, int, struct iov_iter *, struct io_uring_cmd *, struct iou_vec *, _Bool, unsigned int)'} 47 | int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +262 io_uring/uring_cmd.c 257 258 int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, 259 unsigned long nr_segs, int rw, 260 struct iov_iter *iter, 261 struct io_uring_cmd *ioucmd, > 262 struct iou_vec *iou_vec, bool compat, 263 unsigned int issue_flags) 264 { 265 struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); 266 struct iovec *iov; 267 int ret; 268 269 iov = iovec_from_user(uiovec, nr_segs, 0, NULL, compat); 270 if (IS_ERR(iov)) 271 return PTR_ERR(iov); 272 273 ret = io_vec_realloc(iou_vec, nr_segs); 274 if (ret) { 275 kfree(iov); 276 return ret; 277 } 278 memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); 279 kfree(iov); 280 281 ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, 282 issue_flags); 283 return ret; 284 } 285 EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed_vec); 286 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang 2025-03-11 13:08 ` Pavel Begunkov 2025-03-12 9:59 ` kernel test robot @ 2025-03-12 10:10 ` kernel test robot 2 siblings, 0 replies; 10+ messages in thread From: kernel test robot @ 2025-03-12 10:10 UTC (permalink / raw) To: Sidong Yang; +Cc: llvm, oe-kbuild-all Hi Sidong, [This is a private test report for your RFC patch.] kernel test robot noticed the following build warnings: [auto build test WARNING on next-20250307] [also build test WARNING on v6.14-rc6] [cannot apply to kdave/for-next linus/master v6.14-rc6 v6.14-rc5 v6.14-rc4] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sidong-Yang/io_uring-cmd-introduce-io_uring_cmd_import_fixed_vec/20250311-194620 base: next-20250307 patch link: https://lore.kernel.org/r/20250311114053.216359-2-sidong.yang%40furiosa.ai patch subject: [RFC PATCH 1/2] io_uring: cmd: introduce io_uring_cmd_import_fixed_vec config: i386-buildonly-randconfig-002-20250312 (https://download.01.org/0day-ci/archive/20250312/202503121758.aWUV652p-lkp@intel.com/config) compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250312/202503121758.aWUV652p-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503121758.aWUV652p-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from block/ioctl.c:4: In file included from include/linux/blkdev.h:9: In file included from include/linux/blk_types.h:10: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:8: In file included from include/linux/cacheflush.h:5: In file included from arch/x86/include/asm/cacheflush.h:5: In file included from include/linux/mm.h:2306: include/linux/vmstat.h:507:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 507 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ In file included from block/ioctl.c:15: >> include/linux/io_uring/cmd.h:51:14: warning: declaration of 'struct iou_vec' will not be visible outside of this function [-Wvisibility] 51 | struct iou_vec *iou_vec, bool compat, | ^ 2 warnings generated. -- In file included from io_uring/uring_cmd.c:5: In file included from include/linux/io_uring/cmd.h:6: In file included from include/linux/io_uring_types.h:4: In file included from include/linux/blkdev.h:9: In file included from include/linux/blk_types.h:10: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:8: In file included from include/linux/cacheflush.h:5: In file included from arch/x86/include/asm/cacheflush.h:5: In file included from include/linux/mm.h:2306: include/linux/vmstat.h:507:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 507 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ In file included from io_uring/uring_cmd.c:5: >> include/linux/io_uring/cmd.h:51:14: warning: declaration of 'struct iou_vec' will not be visible outside of this function [-Wvisibility] 51 | struct iou_vec *iou_vec, bool compat, | ^ >> io_uring/uring_cmd.c:262:14: warning: declaration of 'struct iou_vec' will not be visible outside of this function [-Wvisibility] 262 | struct iou_vec *iou_vec, bool compat, | ^ io_uring/uring_cmd.c:258:5: error: conflicting types for 'io_uring_cmd_import_fixed_vec' 258 | int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, | ^ include/linux/io_uring/cmd.h:47:5: note: previous declaration is here 47 | int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, | ^ io_uring/uring_cmd.c:273:8: error: call to undeclared function 'io_vec_realloc'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 273 | ret = io_vec_realloc(iou_vec, nr_segs); | ^ io_uring/uring_cmd.c:278:16: error: incomplete definition of type 'struct iou_vec' 278 | memcpy(iou_vec->iovec, iov, sizeof(*iov) * nr_segs); | ~~~~~~~^ arch/x86/include/asm/string_32.h:150:42: note: expanded from macro 'memcpy' 150 | #define memcpy(t, f, n) __builtin_memcpy(t, f, n) | ^ io_uring/uring_cmd.c:262:14: note: forward declaration of 'struct iou_vec' 262 | struct iou_vec *iou_vec, bool compat, | ^ io_uring/uring_cmd.c:281:8: error: call to undeclared function 'io_import_reg_vec'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 281 | ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, | ^ io_uring/uring_cmd.c:281:8: note: did you mean 'io_import_reg_buf'? io_uring/rsrc.h:61:5: note: 'io_import_reg_buf' declared here 61 | int io_import_reg_buf(struct io_kiocb *req, struct iov_iter *iter, | ^ io_uring/uring_cmd.c:281:57: error: incomplete definition of type 'struct iou_vec' 281 | ret = io_import_reg_vec(rw, iter, req, iou_vec, iou_vec->nr, 0, | ~~~~~~~^ io_uring/uring_cmd.c:262:14: note: forward declaration of 'struct iou_vec' 262 | struct iou_vec *iou_vec, bool compat, | ^ 3 warnings and 5 errors generated. vim +51 include/linux/io_uring/cmd.h 40 41 #if defined(CONFIG_IO_URING) 42 int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, 43 struct iov_iter *iter, 44 struct io_uring_cmd *ioucmd, 45 unsigned int issue_flags); 46 47 int io_uring_cmd_import_fixed_vec(const struct iovec __user *uiovec, 48 unsigned long nr_segs, int rw, 49 struct iov_iter *iter, 50 struct io_uring_cmd *ioucmd, > 51 struct iou_vec *iou_vec, bool compat, 52 unsigned int issue_flags); 53 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED 2025-03-11 11:40 [RFC PATCH 0/2] introduce io_uring_cmd_import_fixed_vec Sidong Yang 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang @ 2025-03-11 11:40 ` Sidong Yang 2025-03-11 12:55 ` Pavel Begunkov 2025-03-12 11:11 ` kernel test robot 1 sibling, 2 replies; 10+ messages in thread From: Sidong Yang @ 2025-03-11 11:40 UTC (permalink / raw) To: Jens Axboe, Pavel Begunkov, Josef Bacik, David Sterba Cc: Sidong Yang, io-uring, linux-kernel, linux-btrfs This patch supports IORING_URING_CMD_FIXED flags in io-uring cmd. It means that user provided buf_index in sqe that is registered before submitting requests. In this patch, btrfs_uring_encoded_read() makes iov_iter bvec type by checking the io-uring cmd flag. And there is additional iou_vec field in btrfs_uring_priv for remaining bvecs lifecycle. Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> --- fs/btrfs/ioctl.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6c18bad53cd3..586671eea622 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4643,6 +4643,7 @@ struct btrfs_uring_priv { struct page **pages; unsigned long nr_pages; struct kiocb iocb; + struct iou_vec iou_vec; struct iovec *iov; struct iov_iter iter; struct extent_state *cached_state; @@ -4711,6 +4712,8 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss kfree(priv->pages); kfree(priv->iov); + if (priv->iou_vec.iovec) + kfree(priv->iou_vec.iovec); kfree(priv); } @@ -4730,7 +4733,8 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, struct extent_state *cached_state, u64 disk_bytenr, u64 disk_io_size, size_t count, bool compressed, - struct iovec *iov, struct io_uring_cmd *cmd) + struct iovec *iov, struct io_uring_cmd *cmd, + struct iou_vec *iou_vec) { struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); struct extent_io_tree *io_tree = &inode->io_tree; @@ -4767,6 +4771,7 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, priv->start = start; priv->lockend = lockend; priv->err = 0; + priv->iou_vec = *iou_vec; ret = btrfs_encoded_read_regular_fill_pages(inode, disk_bytenr, disk_io_size, pages, priv); @@ -4818,6 +4823,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue u64 start, lockend; void __user *sqe_addr; struct btrfs_uring_encoded_data *data = io_uring_cmd_get_async_data(cmd)->op_data; + struct iou_vec iou_vec = {}; if (!capable(CAP_SYS_ADMIN)) { ret = -EPERM; @@ -4875,9 +4881,19 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue } data->iov = data->iovstack; - ret = import_iovec(ITER_DEST, data->args.iov, data->args.iovcnt, - ARRAY_SIZE(data->iovstack), &data->iov, - &data->iter); + + if (cmd && (cmd->flags & IORING_URING_CMD_FIXED)) { + ret = io_uring_cmd_import_fixed_vec( + data->args.iov, data->args.iovcnt, ITER_DEST, + &data->iter, cmd, &iou_vec, false, issue_flags); + data->iov = NULL; + } else { + ret = import_iovec(ITER_DEST, data->args.iov, + data->args.iovcnt, + ARRAY_SIZE(data->iovstack), + &data->iov, &data->iter); + } + if (ret < 0) goto out_acct; @@ -4929,7 +4945,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue ret = btrfs_uring_read_extent(&kiocb, &data->iter, start, lockend, cached_state, disk_bytenr, disk_io_size, count, data->args.compression, - data->iov, cmd); + data->iov, cmd, &iou_vec); goto out_acct; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED 2025-03-11 11:40 ` [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED Sidong Yang @ 2025-03-11 12:55 ` Pavel Begunkov 2025-03-12 3:05 ` Sidong Yang 2025-03-12 11:11 ` kernel test robot 1 sibling, 1 reply; 10+ messages in thread From: Pavel Begunkov @ 2025-03-11 12:55 UTC (permalink / raw) To: Sidong Yang, Jens Axboe, Josef Bacik, David Sterba Cc: io-uring, linux-kernel, linux-btrfs On 3/11/25 11:40, Sidong Yang wrote: > This patch supports IORING_URING_CMD_FIXED flags in io-uring cmd. It > means that user provided buf_index in sqe that is registered before > submitting requests. In this patch, btrfs_uring_encoded_read() makes > iov_iter bvec type by checking the io-uring cmd flag. And there is > additional iou_vec field in btrfs_uring_priv for remaining bvecs > lifecycle. > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > --- > fs/btrfs/ioctl.c | 26 +++++++++++++++++++++----- > 1 file changed, 21 insertions(+), 5 deletions(-) > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index 6c18bad53cd3..586671eea622 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -4643,6 +4643,7 @@ struct btrfs_uring_priv { > struct page **pages; > unsigned long nr_pages; > struct kiocb iocb; > + struct iou_vec iou_vec; This structure should not be leaked out of core io_uring ... > struct iovec *iov; > struct iov_iter iter; > struct extent_state *cached_state; > @@ -4711,6 +4712,8 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss > > kfree(priv->pages); > kfree(priv->iov); > + if (priv->iou_vec.iovec) > + kfree(priv->iou_vec.iovec); ... exactly because if this. This line relies on details it shouldn't. -- Pavel Begunkov ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED 2025-03-11 12:55 ` Pavel Begunkov @ 2025-03-12 3:05 ` Sidong Yang 0 siblings, 0 replies; 10+ messages in thread From: Sidong Yang @ 2025-03-12 3:05 UTC (permalink / raw) To: Pavel Begunkov Cc: Jens Axboe, Josef Bacik, David Sterba, io-uring, linux-kernel, linux-btrfs On Tue, Mar 11, 2025 at 12:55:48PM +0000, Pavel Begunkov wrote: Hi Pavel, > On 3/11/25 11:40, Sidong Yang wrote: > > This patch supports IORING_URING_CMD_FIXED flags in io-uring cmd. It > > means that user provided buf_index in sqe that is registered before > > submitting requests. In this patch, btrfs_uring_encoded_read() makes > > iov_iter bvec type by checking the io-uring cmd flag. And there is > > additional iou_vec field in btrfs_uring_priv for remaining bvecs > > lifecycle. > > > > Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai> > > --- > > fs/btrfs/ioctl.c | 26 +++++++++++++++++++++----- > > 1 file changed, 21 insertions(+), 5 deletions(-) > > > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > > index 6c18bad53cd3..586671eea622 100644 > > --- a/fs/btrfs/ioctl.c > > +++ b/fs/btrfs/ioctl.c > > @@ -4643,6 +4643,7 @@ struct btrfs_uring_priv { > > struct page **pages; > > unsigned long nr_pages; > > struct kiocb iocb; > > + struct iou_vec iou_vec; > > This structure should not be leaked out of core io_uring ... Agreed, but this was needed that priv needs to have bvec than iovec. Thinking about this, just adding bvec or make union with iov is simple way to do this. > > > struct iovec *iov; > > struct iov_iter iter; > > struct extent_state *cached_state; > > @@ -4711,6 +4712,8 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss > > kfree(priv->pages); > > kfree(priv->iov); > > + if (priv->iou_vec.iovec) > > + kfree(priv->iou_vec.iovec); > > ... exactly because if this. This line relies on details it > shouldn't. Yes, we don't need this. Thanks, Sidong > > -- > Pavel Begunkov > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED 2025-03-11 11:40 ` [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED Sidong Yang 2025-03-11 12:55 ` Pavel Begunkov @ 2025-03-12 11:11 ` kernel test robot 1 sibling, 0 replies; 10+ messages in thread From: kernel test robot @ 2025-03-12 11:11 UTC (permalink / raw) To: Sidong Yang; +Cc: llvm, oe-kbuild-all Hi Sidong, [This is a private test report for your RFC patch.] kernel test robot noticed the following build errors: [auto build test ERROR on next-20250307] [also build test ERROR on v6.14-rc6] [cannot apply to kdave/for-next linus/master v6.14-rc6 v6.14-rc5 v6.14-rc4] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sidong-Yang/io_uring-cmd-introduce-io_uring_cmd_import_fixed_vec/20250311-194620 base: next-20250307 patch link: https://lore.kernel.org/r/20250311114053.216359-3-sidong.yang%40furiosa.ai patch subject: [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED config: i386-buildonly-randconfig-006-20250312 (https://download.01.org/0day-ci/archive/20250312/202503121808.6NloJdpM-lkp@intel.com/config) compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250312/202503121808.6NloJdpM-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503121808.6NloJdpM-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from fs/btrfs/ioctl.c:7: In file included from include/linux/bio.h:10: In file included from include/linux/blk_types.h:10: In file included from include/linux/bvec.h:10: In file included from include/linux/highmem.h:8: In file included from include/linux/cacheflush.h:5: In file included from arch/x86/include/asm/cacheflush.h:5: In file included from include/linux/mm.h:2306: include/linux/vmstat.h:507:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 507 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ In file included from fs/btrfs/ioctl.c:32: include/linux/io_uring/cmd.h:51:14: warning: declaration of 'struct iou_vec' will not be visible outside of this function [-Wvisibility] 51 | struct iou_vec *iou_vec, bool compat, | ^ >> fs/btrfs/ioctl.c:4647:17: error: field has incomplete type 'struct iou_vec' 4647 | struct iou_vec iou_vec; | ^ fs/btrfs/ioctl.c:4647:9: note: forward declaration of 'struct iou_vec' 4647 | struct iou_vec iou_vec; | ^ >> fs/btrfs/ioctl.c:4827:17: error: variable has incomplete type 'struct iou_vec' 4827 | struct iou_vec iou_vec = {}; | ^ fs/btrfs/ioctl.c:4647:9: note: forward declaration of 'struct iou_vec' 4647 | struct iou_vec iou_vec; | ^ 2 warnings and 2 errors generated. vim +4647 fs/btrfs/ioctl.c 4636 4637 /* 4638 * Context that's attached to an encoded read io_uring command, in cmd->pdu. It 4639 * contains the fields in btrfs_uring_read_extent that are necessary to finish 4640 * off and cleanup the I/O in btrfs_uring_read_finished. 4641 */ 4642 struct btrfs_uring_priv { 4643 struct io_uring_cmd *cmd; 4644 struct page **pages; 4645 unsigned long nr_pages; 4646 struct kiocb iocb; > 4647 struct iou_vec iou_vec; 4648 struct iovec *iov; 4649 struct iov_iter iter; 4650 struct extent_state *cached_state; 4651 u64 count; 4652 u64 start; 4653 u64 lockend; 4654 int err; 4655 bool compressed; 4656 }; 4657 4658 struct io_btrfs_cmd { 4659 struct btrfs_uring_priv *priv; 4660 }; 4661 4662 static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int issue_flags) 4663 { 4664 struct io_btrfs_cmd *bc = io_uring_cmd_to_pdu(cmd, struct io_btrfs_cmd); 4665 struct btrfs_uring_priv *priv = bc->priv; 4666 struct btrfs_inode *inode = BTRFS_I(file_inode(priv->iocb.ki_filp)); 4667 struct extent_io_tree *io_tree = &inode->io_tree; 4668 unsigned long index; 4669 u64 cur; 4670 size_t page_offset; 4671 ssize_t ret; 4672 4673 /* The inode lock has already been acquired in btrfs_uring_read_extent. */ 4674 btrfs_lockdep_inode_acquire(inode, i_rwsem); 4675 4676 if (priv->err) { 4677 ret = priv->err; 4678 goto out; 4679 } 4680 4681 if (priv->compressed) { 4682 index = 0; 4683 page_offset = 0; 4684 } else { 4685 index = (priv->iocb.ki_pos - priv->start) >> PAGE_SHIFT; 4686 page_offset = offset_in_page(priv->iocb.ki_pos - priv->start); 4687 } 4688 cur = 0; 4689 while (cur < priv->count) { 4690 size_t bytes = min_t(size_t, priv->count - cur, PAGE_SIZE - page_offset); 4691 4692 if (copy_page_to_iter(priv->pages[index], page_offset, bytes, 4693 &priv->iter) != bytes) { 4694 ret = -EFAULT; 4695 goto out; 4696 } 4697 4698 index++; 4699 cur += bytes; 4700 page_offset = 0; 4701 } 4702 ret = priv->count; 4703 4704 out: 4705 unlock_extent(io_tree, priv->start, priv->lockend, &priv->cached_state); 4706 btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); 4707 4708 io_uring_cmd_done(cmd, ret, 0, issue_flags); 4709 add_rchar(current, ret); 4710 4711 for (index = 0; index < priv->nr_pages; index++) 4712 __free_page(priv->pages[index]); 4713 4714 kfree(priv->pages); 4715 kfree(priv->iov); 4716 if (priv->iou_vec.iovec) 4717 kfree(priv->iou_vec.iovec); 4718 kfree(priv); 4719 } 4720 4721 void btrfs_uring_read_extent_endio(void *ctx, int err) 4722 { 4723 struct btrfs_uring_priv *priv = ctx; 4724 struct io_btrfs_cmd *bc = io_uring_cmd_to_pdu(priv->cmd, struct io_btrfs_cmd); 4725 4726 priv->err = err; 4727 bc->priv = priv; 4728 4729 io_uring_cmd_complete_in_task(priv->cmd, btrfs_uring_read_finished); 4730 } 4731 4732 static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, 4733 u64 start, u64 lockend, 4734 struct extent_state *cached_state, 4735 u64 disk_bytenr, u64 disk_io_size, 4736 size_t count, bool compressed, 4737 struct iovec *iov, struct io_uring_cmd *cmd, 4738 struct iou_vec *iou_vec) 4739 { 4740 struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); 4741 struct extent_io_tree *io_tree = &inode->io_tree; 4742 struct page **pages; 4743 struct btrfs_uring_priv *priv = NULL; 4744 unsigned long nr_pages; 4745 int ret; 4746 4747 nr_pages = DIV_ROUND_UP(disk_io_size, PAGE_SIZE); 4748 pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); 4749 if (!pages) 4750 return -ENOMEM; 4751 ret = btrfs_alloc_page_array(nr_pages, pages, 0); 4752 if (ret) { 4753 ret = -ENOMEM; 4754 goto out_fail; 4755 } 4756 4757 priv = kmalloc(sizeof(*priv), GFP_NOFS); 4758 if (!priv) { 4759 ret = -ENOMEM; 4760 goto out_fail; 4761 } 4762 4763 priv->iocb = *iocb; 4764 priv->iov = iov; 4765 priv->iter = *iter; 4766 priv->count = count; 4767 priv->cmd = cmd; 4768 priv->cached_state = cached_state; 4769 priv->compressed = compressed; 4770 priv->nr_pages = nr_pages; 4771 priv->pages = pages; 4772 priv->start = start; 4773 priv->lockend = lockend; 4774 priv->err = 0; 4775 priv->iou_vec = *iou_vec; 4776 4777 ret = btrfs_encoded_read_regular_fill_pages(inode, disk_bytenr, 4778 disk_io_size, pages, priv); 4779 if (ret && ret != -EIOCBQUEUED) 4780 goto out_fail; 4781 4782 /* 4783 * If we return -EIOCBQUEUED, we're deferring the cleanup to 4784 * btrfs_uring_read_finished(), which will handle unlocking the extent 4785 * and inode and freeing the allocations. 4786 */ 4787 4788 /* 4789 * We're returning to userspace with the inode lock held, and that's 4790 * okay - it'll get unlocked in a worker thread. Call 4791 * btrfs_lockdep_inode_release() to avoid confusing lockdep. 4792 */ 4793 btrfs_lockdep_inode_release(inode, i_rwsem); 4794 4795 return -EIOCBQUEUED; 4796 4797 out_fail: 4798 unlock_extent(io_tree, start, lockend, &cached_state); 4799 btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); 4800 kfree(priv); 4801 return ret; 4802 } 4803 4804 struct btrfs_uring_encoded_data { 4805 struct btrfs_ioctl_encoded_io_args args; 4806 struct iovec iovstack[UIO_FASTIOV]; 4807 struct iovec *iov; 4808 struct iov_iter iter; 4809 }; 4810 4811 static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue_flags) 4812 { 4813 size_t copy_end_kernel = offsetofend(struct btrfs_ioctl_encoded_io_args, flags); 4814 size_t copy_end; 4815 int ret; 4816 u64 disk_bytenr, disk_io_size; 4817 struct file *file; 4818 struct btrfs_inode *inode; 4819 struct btrfs_fs_info *fs_info; 4820 struct extent_io_tree *io_tree; 4821 loff_t pos; 4822 struct kiocb kiocb; 4823 struct extent_state *cached_state = NULL; 4824 u64 start, lockend; 4825 void __user *sqe_addr; 4826 struct btrfs_uring_encoded_data *data = io_uring_cmd_get_async_data(cmd)->op_data; > 4827 struct iou_vec iou_vec = {}; 4828 4829 if (!capable(CAP_SYS_ADMIN)) { 4830 ret = -EPERM; 4831 goto out_acct; 4832 } 4833 file = cmd->file; 4834 inode = BTRFS_I(file->f_inode); 4835 fs_info = inode->root->fs_info; 4836 io_tree = &inode->io_tree; 4837 sqe_addr = u64_to_user_ptr(READ_ONCE(cmd->sqe->addr)); 4838 4839 if (issue_flags & IO_URING_F_COMPAT) { 4840 #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) 4841 copy_end = offsetofend(struct btrfs_ioctl_encoded_io_args_32, flags); 4842 #else 4843 return -ENOTTY; 4844 #endif 4845 } else { 4846 copy_end = copy_end_kernel; 4847 } 4848 4849 if (!data) { 4850 data = kzalloc(sizeof(*data), GFP_NOFS); 4851 if (!data) { 4852 ret = -ENOMEM; 4853 goto out_acct; 4854 } 4855 4856 io_uring_cmd_get_async_data(cmd)->op_data = data; 4857 4858 if (issue_flags & IO_URING_F_COMPAT) { 4859 #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) 4860 struct btrfs_ioctl_encoded_io_args_32 args32; 4861 4862 if (copy_from_user(&args32, sqe_addr, copy_end)) { 4863 ret = -EFAULT; 4864 goto out_acct; 4865 } 4866 4867 data->args.iov = compat_ptr(args32.iov); 4868 data->args.iovcnt = args32.iovcnt; 4869 data->args.offset = args32.offset; 4870 data->args.flags = args32.flags; 4871 #endif 4872 } else { 4873 if (copy_from_user(&data->args, sqe_addr, copy_end)) { 4874 ret = -EFAULT; 4875 goto out_acct; 4876 } 4877 } 4878 4879 if (data->args.flags != 0) { 4880 ret = -EINVAL; 4881 goto out_acct; 4882 } 4883 4884 data->iov = data->iovstack; 4885 4886 if (cmd && (cmd->flags & IORING_URING_CMD_FIXED)) { 4887 ret = io_uring_cmd_import_fixed_vec( 4888 data->args.iov, data->args.iovcnt, ITER_DEST, 4889 &data->iter, cmd, &iou_vec, false, issue_flags); 4890 data->iov = NULL; 4891 } else { 4892 ret = import_iovec(ITER_DEST, data->args.iov, 4893 data->args.iovcnt, 4894 ARRAY_SIZE(data->iovstack), 4895 &data->iov, &data->iter); 4896 } 4897 4898 if (ret < 0) 4899 goto out_acct; 4900 4901 if (iov_iter_count(&data->iter) == 0) { 4902 ret = 0; 4903 goto out_free; 4904 } 4905 } 4906 4907 pos = data->args.offset; 4908 ret = rw_verify_area(READ, file, &pos, data->args.len); 4909 if (ret < 0) 4910 goto out_free; 4911 4912 init_sync_kiocb(&kiocb, file); 4913 kiocb.ki_pos = pos; 4914 4915 if (issue_flags & IO_URING_F_NONBLOCK) 4916 kiocb.ki_flags |= IOCB_NOWAIT; 4917 4918 start = ALIGN_DOWN(pos, fs_info->sectorsize); 4919 lockend = start + BTRFS_MAX_UNCOMPRESSED - 1; 4920 4921 ret = btrfs_encoded_read(&kiocb, &data->iter, &data->args, &cached_state, 4922 &disk_bytenr, &disk_io_size); 4923 if (ret < 0 && ret != -EIOCBQUEUED) 4924 goto out_free; 4925 4926 file_accessed(file); 4927 4928 if (copy_to_user(sqe_addr + copy_end, 4929 (const char *)&data->args + copy_end_kernel, 4930 sizeof(data->args) - copy_end_kernel)) { 4931 if (ret == -EIOCBQUEUED) { 4932 unlock_extent(io_tree, start, lockend, &cached_state); 4933 btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); 4934 } 4935 ret = -EFAULT; 4936 goto out_free; 4937 } 4938 4939 if (ret == -EIOCBQUEUED) { 4940 u64 count = min_t(u64, iov_iter_count(&data->iter), disk_io_size); 4941 4942 /* Match ioctl by not returning past EOF if uncompressed. */ 4943 if (!data->args.compression) 4944 count = min_t(u64, count, data->args.len); 4945 4946 ret = btrfs_uring_read_extent(&kiocb, &data->iter, start, lockend, 4947 cached_state, disk_bytenr, disk_io_size, 4948 count, data->args.compression, 4949 data->iov, cmd, &iou_vec); 4950 4951 goto out_acct; 4952 } 4953 4954 out_free: 4955 kfree(data->iov); 4956 4957 out_acct: 4958 if (ret > 0) 4959 add_rchar(current, ret); 4960 inc_syscr(current); 4961 4962 return ret; 4963 } 4964 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-03-12 11:12 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-03-11 11:40 [RFC PATCH 0/2] introduce io_uring_cmd_import_fixed_vec Sidong Yang 2025-03-11 11:40 ` [RFC PATCH 1/2] io_uring: cmd: " Sidong Yang 2025-03-11 13:08 ` Pavel Begunkov 2025-03-12 3:08 ` Sidong Yang 2025-03-12 9:59 ` kernel test robot 2025-03-12 10:10 ` kernel test robot 2025-03-11 11:40 ` [RFC PATCH 2/2] btrfs: ioctl: use registered buffer for IORING_URING_CMD_FIXED Sidong Yang 2025-03-11 12:55 ` Pavel Begunkov 2025-03-12 3:05 ` Sidong Yang 2025-03-12 11:11 ` kernel test robot
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.