* [PATCH v3 0/3] io_uring: add getdents64 support
@ 2021-11-25 23:25 Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 1/3] fs: add parameter use_fpos to iterate_dir function Stefan Roesch
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-11-25 23:25 UTC (permalink / raw)
To: io-uring, linux-fsdevel; +Cc: shr
This series adds support for getdents64 in liburing. The intent is to
provide a more complete I/O interface for io_uring.
Patch 1: fs: add parameter use_fpos to iterate_dir()
This adds a new parameter to the function iterate_dir() so the
caller can specify if the position is the file position or the
position stored in the buffer context.
Patch 2: fs: split off vfs_getdents function from getdents64 system call
This splits of the iterate_dir part of the syscall in its own
dedicated function. This allows to call the function directly from
liburing.
Patch 3: io_uring: add support for getdents64
Adds the functions to io_uring to support getdents64.
There is also a patch series for the changes to liburing. This includes
a new test. The patch series is called "liburing: add getdents support."
The following tests have been performed:
- new liburing getdents test program has been run
- xfstests have been run
- both tests have been repeated with the kernel memory leak checker
and no leaks have been reported.
Signed-off-by: Stefan Roesch <[email protected]>
---
V3: - add do_iterate_dir() function to Patch 1
- make iterate_dir() function call do_iterate_dir()
This has the advantage that the function signature of iterate_dir
does not change
V2: Updated the iterate_dir calls in fs/ksmbd, fs/ecryptfs and arch/alpha with
the additional parameter.
Stefan Roesch (3):
fs: add parameter use_fpos to iterate_dir function
fs: split off vfs_getdents function of getdents64 syscall
io_uring: add support for getdents64
fs/internal.h | 8 +++++
fs/io_uring.c | 52 +++++++++++++++++++++++++++++
fs/readdir.c | 61 ++++++++++++++++++++++++++++-------
include/uapi/linux/io_uring.h | 1 +
4 files changed, 110 insertions(+), 12 deletions(-)
base-commit: de5de0813b7dbbb71fb5d677ed823505a0e685c5
--
2.30.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/3] fs: add parameter use_fpos to iterate_dir function
2021-11-25 23:25 [PATCH v3 0/3] io_uring: add getdents64 support Stefan Roesch
@ 2021-11-25 23:25 ` Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 3/3] io_uring: add support for getdents64 Stefan Roesch
2 siblings, 0 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-11-25 23:25 UTC (permalink / raw)
To: io-uring, linux-fsdevel; +Cc: shr
This adds the use_fpos parameter to the iterate_dir function.
If use_fpos is true it uses the file position in the file
structure (existing behavior). If use_fpos is false, it uses
the pos in the context structure.
This change is required to support getdents in io_uring.
Signed-off-by: Stefan Roesch <[email protected]>
---
fs/readdir.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/fs/readdir.c b/fs/readdir.c
index 09e8ed7d4161..e9c197edf73a 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -36,8 +36,15 @@
unsafe_copy_to_user(dst, src, len, label); \
} while (0)
-
-int iterate_dir(struct file *file, struct dir_context *ctx)
+/**
+ * do_iterate_dir - iterate over directory
+ * @file : pointer to file struct of directory
+ * @ctx : pointer to directory ctx structure
+ * @use_fpos: true : use file offset
+ * false: use pos in ctx structure
+ */
+static int do_iterate_dir(struct file *file, struct dir_context *ctx,
+ bool use_fpos)
{
struct inode *inode = file_inode(file);
bool shared = false;
@@ -60,12 +67,17 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
res = -ENOENT;
if (!IS_DEADDIR(inode)) {
- ctx->pos = file->f_pos;
+ if (use_fpos)
+ ctx->pos = file->f_pos;
+
if (shared)
res = file->f_op->iterate_shared(file, ctx);
else
res = file->f_op->iterate(file, ctx);
- file->f_pos = ctx->pos;
+
+ if (use_fpos)
+ file->f_pos = ctx->pos;
+
fsnotify_access(file);
file_accessed(file);
}
@@ -76,6 +88,11 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
out:
return res;
}
+
+int iterate_dir(struct file *file, struct dir_context *ctx)
+{
+ return do_iterate_dir(file, ctx, true);
+}
EXPORT_SYMBOL(iterate_dir);
/*
--
2.30.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall
2021-11-25 23:25 [PATCH v3 0/3] io_uring: add getdents64 support Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 1/3] fs: add parameter use_fpos to iterate_dir function Stefan Roesch
@ 2021-11-25 23:25 ` Stefan Roesch
2021-11-26 6:44 ` kernel test robot
2021-11-26 8:43 ` kernel test robot
2021-11-25 23:25 ` [PATCH v3 3/3] io_uring: add support for getdents64 Stefan Roesch
2 siblings, 2 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-11-25 23:25 UTC (permalink / raw)
To: io-uring, linux-fsdevel; +Cc: shr
This splits off the vfs_getdents function from the getdents64 system
call. This allows io_uring to call the function.
Signed-off-by: Stefan Roesch <[email protected]>
---
fs/internal.h | 8 ++++++++
fs/readdir.c | 36 ++++++++++++++++++++++++++++--------
2 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/fs/internal.h b/fs/internal.h
index 7979ff8d168c..355be993b9f1 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -194,3 +194,11 @@ long splice_file_to_pipe(struct file *in,
struct pipe_inode_info *opipe,
loff_t *offset,
size_t len, unsigned int flags);
+
+/*
+ * fs/readdir.c
+ */
+struct linux_dirent64;
+
+int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
+ unsigned int count, s64 pos);
diff --git a/fs/readdir.c b/fs/readdir.c
index e9c197edf73a..c9ee066cd677 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -368,22 +368,26 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
return -EFAULT;
}
-SYSCALL_DEFINE3(getdents64, unsigned int, fd,
- struct linux_dirent64 __user *, dirent, unsigned int, count)
+/**
+ * vfs_getdents - getdents without fdget
+ * @file : pointer to file struct of directory
+ * @dirent : pointer to user directory structure
+ * @count : size of buffer
+ * @ctx_pos : if file pos is used, pass -1,
+ * if ctx pos is used, pass ctx pos
+ */
+int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
+ unsigned int count, s64 ctx_pos)
{
- struct fd f;
struct getdents_callback64 buf = {
.ctx.actor = filldir64,
+ .ctx.pos = ctx_pos,
.count = count,
.current_dir = dirent
};
int error;
- f = fdget_pos(fd);
- if (!f.file)
- return -EBADF;
-
- error = iterate_dir(f.file, &buf.ctx);
+ error = do_iterate_dir(file, &buf.ctx, ctx_pos < 0);
if (error >= 0)
error = buf.error;
if (buf.prev_reclen) {
@@ -396,6 +400,22 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
else
error = count - buf.count;
}
+
+ return error;
+}
+
+SYSCALL_DEFINE3(getdents64, unsigned int, fd,
+ struct linux_dirent64 __user *, dirent, unsigned int, count)
+{
+ struct fd f;
+ int error;
+
+ f = fdget_pos(fd);
+ if (!f.file)
+ return -EBADF;
+
+ error = vfs_getdents(f.file, dirent, count, -1);
+
fdput_pos(f);
return error;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/3] io_uring: add support for getdents64
2021-11-25 23:25 [PATCH v3 0/3] io_uring: add getdents64 support Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 1/3] fs: add parameter use_fpos to iterate_dir function Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
@ 2021-11-25 23:25 ` Stefan Roesch
2 siblings, 0 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-11-25 23:25 UTC (permalink / raw)
To: io-uring, linux-fsdevel; +Cc: shr, Pavel Begunkov
This adds support for getdents64 to io_uring.
Signed-off-by: Stefan Roesch <[email protected]>
Reviewed-by: Pavel Begunkov <[email protected]>
---
fs/io_uring.c | 52 +++++++++++++++++++++++++++++++++++
include/uapi/linux/io_uring.h | 1 +
2 files changed, 53 insertions(+)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 08b1b3de9b3f..8fdff4745742 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -691,6 +691,13 @@ struct io_hardlink {
int flags;
};
+struct io_getdents {
+ struct file *file;
+ struct linux_dirent64 __user *dirent;
+ unsigned int count;
+ loff_t pos;
+};
+
struct io_async_connect {
struct sockaddr_storage address;
};
@@ -856,6 +863,7 @@ struct io_kiocb {
struct io_mkdir mkdir;
struct io_symlink symlink;
struct io_hardlink hardlink;
+ struct io_getdents getdents;
};
u8 opcode;
@@ -1105,6 +1113,9 @@ static const struct io_op_def io_op_defs[] = {
[IORING_OP_MKDIRAT] = {},
[IORING_OP_SYMLINKAT] = {},
[IORING_OP_LINKAT] = {},
+ [IORING_OP_GETDENTS] = {
+ .needs_file = 1,
+ },
};
/* requests with any of those set should undergo io_disarm_next() */
@@ -3971,6 +3982,42 @@ static int io_linkat(struct io_kiocb *req, unsigned int issue_flags)
return 0;
}
+static int io_getdents_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ struct io_getdents *getdents = &req->getdents;
+
+ if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
+ return -EINVAL;
+ if (sqe->ioprio || sqe->rw_flags || sqe->buf_index)
+ return -EINVAL;
+
+ getdents->pos = READ_ONCE(sqe->off);
+ getdents->dirent = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ getdents->count = READ_ONCE(sqe->len);
+
+ return 0;
+}
+
+static int io_getdents(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_getdents *getdents = &req->getdents;
+ int ret;
+
+ if (issue_flags & IO_URING_F_NONBLOCK)
+ return -EAGAIN;
+
+ ret = vfs_getdents(req->file, getdents->dirent, getdents->count, getdents->pos);
+ if (ret < 0) {
+ if (ret == -ERESTARTSYS)
+ ret = -EINTR;
+
+ req_set_fail(req);
+ }
+
+ io_req_complete(req, ret);
+ return 0;
+}
+
static int io_shutdown_prep(struct io_kiocb *req,
const struct io_uring_sqe *sqe)
{
@@ -6486,6 +6533,8 @@ 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_GETDENTS:
+ return io_getdents_prep(req, sqe);
}
printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
@@ -6771,6 +6820,9 @@ 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_GETDENTS:
+ ret = io_getdents(req, issue_flags);
+ break;
default:
ret = -EINVAL;
break;
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 787f491f0d2a..57dc88db5793 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -143,6 +143,7 @@ enum {
IORING_OP_MKDIRAT,
IORING_OP_SYMLINKAT,
IORING_OP_LINKAT,
+ IORING_OP_GETDENTS,
/* this goes last, obviously */
IORING_OP_LAST,
--
2.30.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall
2021-11-25 23:25 ` [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
@ 2021-11-26 6:44 ` kernel test robot
2021-11-26 8:43 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-11-26 6:44 UTC (permalink / raw)
To: Stefan Roesch, io-uring, linux-fsdevel; +Cc: llvm, kbuild-all, shr
Hi Stefan,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on de5de0813b7dbbb71fb5d677ed823505a0e685c5]
url: https://github.com/0day-ci/linux/commits/Stefan-Roesch/io_uring-add-getdents64-support/20211126-072952
base: de5de0813b7dbbb71fb5d677ed823505a0e685c5
config: mips-buildonly-randconfig-r003-20211125 (https://download.01.org/0day-ci/archive/20211126/[email protected]/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 0332d105b9ad7f1f0ffca7e78b71de8b3a48f158)
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/018019be0b26997402fe7ba8367e5260ec2aa8c8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stefan-Roesch/io_uring-add-getdents64-support/20211126-072952
git checkout 018019be0b26997402fe7ba8367e5260ec2aa8c8
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=mips
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> fs/readdir.c:379:5: warning: no previous prototype for function 'vfs_getdents' [-Wmissing-prototypes]
int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
^
fs/readdir.c:379:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
^
static
1 warning generated.
vim +/vfs_getdents +379 fs/readdir.c
370
371 /**
372 * vfs_getdents - getdents without fdget
373 * @file : pointer to file struct of directory
374 * @dirent : pointer to user directory structure
375 * @count : size of buffer
376 * @ctx_pos : if file pos is used, pass -1,
377 * if ctx pos is used, pass ctx pos
378 */
> 379 int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
380 unsigned int count, s64 ctx_pos)
381 {
382 struct getdents_callback64 buf = {
383 .ctx.actor = filldir64,
384 .ctx.pos = ctx_pos,
385 .count = count,
386 .current_dir = dirent
387 };
388 int error;
389
390 error = do_iterate_dir(file, &buf.ctx, ctx_pos < 0);
391 if (error >= 0)
392 error = buf.error;
393 if (buf.prev_reclen) {
394 struct linux_dirent64 __user * lastdirent;
395 typeof(lastdirent->d_off) d_off = buf.ctx.pos;
396
397 lastdirent = (void __user *) buf.current_dir - buf.prev_reclen;
398 if (put_user(d_off, &lastdirent->d_off))
399 error = -EFAULT;
400 else
401 error = count - buf.count;
402 }
403
404 return error;
405 }
406
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall
2021-11-25 23:25 ` [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
2021-11-26 6:44 ` kernel test robot
@ 2021-11-26 8:43 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-11-26 8:43 UTC (permalink / raw)
To: Stefan Roesch, io-uring, linux-fsdevel; +Cc: kbuild-all, shr
Hi Stefan,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on de5de0813b7dbbb71fb5d677ed823505a0e685c5]
url: https://github.com/0day-ci/linux/commits/Stefan-Roesch/io_uring-add-getdents64-support/20211126-072952
base: de5de0813b7dbbb71fb5d677ed823505a0e685c5
config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20211126/[email protected]/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# https://github.com/0day-ci/linux/commit/018019be0b26997402fe7ba8367e5260ec2aa8c8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stefan-Roesch/io_uring-add-getdents64-support/20211126-072952
git checkout 018019be0b26997402fe7ba8367e5260ec2aa8c8
# save the config file to linux build tree
make W=1 ARCH=um SUBARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> fs/readdir.c:379:5: warning: no previous prototype for 'vfs_getdents' [-Wmissing-prototypes]
379 | int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
| ^~~~~~~~~~~~
vim +/vfs_getdents +379 fs/readdir.c
370
371 /**
372 * vfs_getdents - getdents without fdget
373 * @file : pointer to file struct of directory
374 * @dirent : pointer to user directory structure
375 * @count : size of buffer
376 * @ctx_pos : if file pos is used, pass -1,
377 * if ctx pos is used, pass ctx pos
378 */
> 379 int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
380 unsigned int count, s64 ctx_pos)
381 {
382 struct getdents_callback64 buf = {
383 .ctx.actor = filldir64,
384 .ctx.pos = ctx_pos,
385 .count = count,
386 .current_dir = dirent
387 };
388 int error;
389
390 error = do_iterate_dir(file, &buf.ctx, ctx_pos < 0);
391 if (error >= 0)
392 error = buf.error;
393 if (buf.prev_reclen) {
394 struct linux_dirent64 __user * lastdirent;
395 typeof(lastdirent->d_off) d_off = buf.ctx.pos;
396
397 lastdirent = (void __user *) buf.current_dir - buf.prev_reclen;
398 if (put_user(d_off, &lastdirent->d_off))
399 error = -EFAULT;
400 else
401 error = count - buf.count;
402 }
403
404 return error;
405 }
406
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-11-26 8:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-11-25 23:25 [PATCH v3 0/3] io_uring: add getdents64 support Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 1/3] fs: add parameter use_fpos to iterate_dir function Stefan Roesch
2021-11-25 23:25 ` [PATCH v3 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
2021-11-26 6:44 ` kernel test robot
2021-11-26 8:43 ` kernel test robot
2021-11-25 23:25 ` [PATCH v3 3/3] io_uring: add support for getdents64 Stefan Roesch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox