public inbox for [email protected]
 help / color / mirror / Atom feed
* [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