All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/3] io_uring: add getdents64 support
@ 2021-12-22 21:07 Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function Stefan Roesch
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-12-22 21:07 UTC (permalink / raw)
  To: linux-nfs; +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 offset parameter to iterate_dir function.
  This adds an offset parameter to the iterate_dir()
  function. The new parameter allows the caller to specify
  the offset to use.

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
  io_uring.

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.


V7: - add loff_t *parameter to iterate_dir function
    - remove do_iterate_dir function
    - change callers of iterate_dir function
v6: - rebased patch series
v5: - remove old patch (v4 contained a patch file from v3)
V4: - silence compiler warnings
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 offset parameter to iterate_dir function
  fs: split off vfs_getdents function of getdents64 syscall
  io_uring: add support for getdents64

 arch/alpha/kernel/osf_sys.c   |  2 +-
 fs/ecryptfs/file.c            |  2 +-
 fs/exportfs/expfs.c           |  2 +-
 fs/internal.h                 |  8 +++++
 fs/io_uring.c                 | 52 +++++++++++++++++++++++++++++
 fs/ksmbd/smb2pdu.c            |  3 +-
 fs/ksmbd/vfs.c                |  4 +--
 fs/nfsd/nfs4recover.c         |  2 +-
 fs/nfsd/vfs.c                 |  2 +-
 fs/overlayfs/readdir.c        |  6 ++--
 fs/readdir.c                  | 62 +++++++++++++++++++++++++----------
 include/linux/fs.h            |  2 +-
 include/uapi/linux/io_uring.h |  1 +
 13 files changed, 119 insertions(+), 29 deletions(-)


base-commit: d09358c3d161dcea8f02eae1281bc996819cc769
-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v7 1/3] fs: add offset parameter to iterate_dir function
  2021-12-22 21:07 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
@ 2021-12-22 21:07 ` Stefan Roesch
  2021-12-24 17:25   ` [PATCH v7 1/3] " Chuck Lever III
  2021-12-22 21:07 ` [PATCH v7 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 3/3] io_uring: add support for getdents64 Stefan Roesch
  2 siblings, 1 reply; 6+ messages in thread
From: Stefan Roesch @ 2021-12-22 21:07 UTC (permalink / raw)
  To: linux-nfs; +Cc: shr

This change adds the offset parameter to the iterate_dir
function. The offset paramater allows the caller to specify
the offset position.

This change is required to support getdents in io_uring.

Signed-off-by: Stefan Roesch <shr@fb.com>
---
 arch/alpha/kernel/osf_sys.c |  2 +-
 fs/ecryptfs/file.c          |  2 +-
 fs/exportfs/expfs.c         |  2 +-
 fs/ksmbd/smb2pdu.c          |  3 ++-
 fs/ksmbd/vfs.c              |  4 ++--
 fs/nfsd/nfs4recover.c       |  2 +-
 fs/nfsd/vfs.c               |  2 +-
 fs/overlayfs/readdir.c      |  6 +++---
 fs/readdir.c                | 28 ++++++++++++++++++----------
 include/linux/fs.h          |  2 +-
 10 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 8bbeebb73cf0..cf68c459bca6 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -162,7 +162,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
 	if (!arg.file)
 		return -EBADF;
 
-	error = iterate_dir(arg.file, &buf.ctx);
+	error = iterate_dir(arg.file, &buf.ctx, &arg.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (count != buf.count)
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 18d5b91cb573..b68f1945e615 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -109,7 +109,7 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
 		.sb = inode->i_sb,
 	};
 	lower_file = ecryptfs_file_to_lower(file);
-	rc = iterate_dir(lower_file, &buf.ctx);
+	rc = iterate_dir(lower_file, &buf.ctx, &lower_file->f_pos);
 	ctx->pos = buf.ctx.pos;
 	if (rc < 0)
 		goto out;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 0106eba46d5a..654e2d4b1d4f 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -323,7 +323,7 @@ static int get_name(const struct path *path, char *name, struct dentry *child)
 	while (1) {
 		int old_seq = buffer.sequence;
 
-		error = iterate_dir(file, &buffer.ctx);
+		error = iterate_dir(file, &buffer.ctx, &file->f_pos);
 		if (buffer.found) {
 			error = 0;
 			break;
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 49c9da37315c..fd4cb995d06d 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -3925,7 +3925,8 @@ int smb2_query_dir(struct ksmbd_work *work)
 	dir_fp->readdir_data.private		= &query_dir_private;
 	set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
 
-	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
+	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx,
+			&dir_fp->filp->f_pos);
 	if (rc == 0)
 		restart_ctx(&dir_fp->readdir_data.ctx);
 	if (rc == -ENOSPC)
diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
index 19d36393974c..5b8e23d3c846 100644
--- a/fs/ksmbd/vfs.c
+++ b/fs/ksmbd/vfs.c
@@ -1136,7 +1136,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
 	set_ctx_actor(&readdir_data.ctx, __dir_empty);
 	readdir_data.dirent_count = 0;
 
-	err = iterate_dir(fp->filp, &readdir_data.ctx);
+	err = iterate_dir(fp->filp, &readdir_data.ctx, &fp->filp->f_pos);
 	if (readdir_data.dirent_count > 2)
 		err = -ENOTEMPTY;
 	else
@@ -1186,7 +1186,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen)
 	if (IS_ERR(dfilp))
 		return PTR_ERR(dfilp);
 
-	ret = iterate_dir(dfilp, &readdir_data.ctx);
+	ret = iterate_dir(dfilp, &readdir_data.ctx, &dfilp->f_pos);
 	if (readdir_data.dirent_count > 0)
 		ret = 0;
 	fput(dfilp);
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 6fedc49726bf..79a2799891e4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -307,7 +307,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 		return status;
 	}
 
-	status = iterate_dir(nn->rec_file, &ctx.ctx);
+	status = iterate_dir(nn->rec_file, &ctx.ctx, &nn->rec_file->f_pos);
 	inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c99857689e2c..085864c25318 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1980,7 +1980,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
 		buf.used = 0;
 		buf.full = 0;
 
-		host_err = iterate_dir(file, &buf.ctx);
+		host_err = iterate_dir(file, &buf.ctx, &file->f_pos);
 		if (buf.full)
 			host_err = 0;
 
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 150fdf3bc68d..52167ff9e513 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -306,7 +306,7 @@ static inline int ovl_dir_read(struct path *realpath,
 	do {
 		rdd->count = 0;
 		rdd->err = 0;
-		err = iterate_dir(realfile, &rdd->ctx);
+		err = iterate_dir(realfile, &rdd->ctx, &realfile->f_pos);
 		if (err >= 0)
 			err = rdd->err;
 	} while (!err && rdd->count);
@@ -722,7 +722,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
 			return PTR_ERR(rdt.cache);
 	}
 
-	err = iterate_dir(od->realfile, &rdt.ctx);
+	err = iterate_dir(od->realfile, &rdt.ctx, &od->realfile->f_pos);
 	ctx->pos = rdt.ctx.pos;
 
 	return err;
@@ -753,7 +753,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
 		      OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
 			err = ovl_iterate_real(file, ctx);
 		} else {
-			err = iterate_dir(od->realfile, ctx);
+			err = iterate_dir(od->realfile, ctx, &od->realfile->f_pos);
 		}
 		goto out;
 	}
diff --git a/fs/readdir.c b/fs/readdir.c
index 09e8ed7d4161..c1e6612e0f47 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -36,8 +36,13 @@
 	unsafe_copy_to_user(dst, src, len, label);		\
 } while (0)
 
-
-int iterate_dir(struct file *file, struct dir_context *ctx)
+/**
+ * iterate_dir - iterate over directory
+ * @file    : pointer to file struct of directory
+ * @ctx     : pointer to directory ctx structure
+ * @pos     : file offset
+ */
+int iterate_dir(struct file *file, struct dir_context *ctx, loff_t *pos)
 {
 	struct inode *inode = file_inode(file);
 	bool shared = false;
@@ -60,12 +65,15 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
 
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
-		ctx->pos = file->f_pos;
+		ctx->pos = *pos;
+
 		if (shared)
 			res = file->f_op->iterate_shared(file, ctx);
 		else
 			res = file->f_op->iterate(file, ctx);
-		file->f_pos = ctx->pos;
+
+		*pos = ctx->pos;
+
 		fsnotify_access(file);
 		file_accessed(file);
 	}
@@ -190,7 +198,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (buf.result)
 		error = buf.result;
 
@@ -283,7 +291,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
@@ -366,7 +374,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
@@ -379,7 +387,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
 		else
 			error = count - buf.count;
 	}
-	fdput_pos(f);
+
 	return error;
 }
 
@@ -448,7 +456,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (buf.result)
 		error = buf.result;
 
@@ -534,7 +542,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6b8dc1a78df6..e1becbe86b07 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3340,7 +3340,7 @@ const char *simple_get_link(struct dentry *, struct inode *,
 			    struct delayed_call *);
 extern const struct inode_operations simple_symlink_inode_operations;
 
-extern int iterate_dir(struct file *, struct dir_context *);
+extern int iterate_dir(struct file *, struct dir_context *, loff_t *pos);
 
 int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 		int flags);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v7 2/3] fs: split off vfs_getdents function of getdents64 syscall
  2021-12-22 21:07 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function Stefan Roesch
@ 2021-12-22 21:07 ` Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 3/3] io_uring: add support for getdents64 Stefan Roesch
  2 siblings, 0 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-12-22 21:07 UTC (permalink / raw)
  To: linux-nfs; +Cc: shr, Christian Brauner

This splits off the vfs_getdents function from the getdents64 system
call. This allows io_uring to call the vfs_getdents function.

Signed-off-by: Stefan Roesch <shr@fb.com>
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
---
 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..432ea3ce76ec 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, loff_t *pos);
diff --git a/fs/readdir.c b/fs/readdir.c
index c1e6612e0f47..1b1fade87525 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -21,6 +21,7 @@
 #include <linux/unistd.h>
 #include <linux/compat.h>
 #include <linux/uaccess.h>
+#include "internal.h"
 
 #include <asm/unaligned.h>
 
@@ -359,22 +360,25 @@ 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
+ * @pos     : file pos
+ */
+int vfs_getdents(struct file *file, struct linux_dirent64 __user *dirent,
+		 unsigned int count, loff_t *pos)
 {
-	struct fd f;
 	struct getdents_callback64 buf = {
 		.ctx.actor = filldir64,
+		.ctx.pos = *pos,
 		.count = count,
 		.current_dir = dirent
 	};
 	int error;
 
-	f = fdget_pos(fd);
-	if (!f.file)
-		return -EBADF;
-
-	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
+	error = iterate_dir(file, &buf.ctx, pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
@@ -391,6 +395,22 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
 	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, &f.file->f_pos);
+
+	fdput_pos(f);
+	return error;
+ }
+
 #ifdef CONFIG_COMPAT
 struct compat_old_linux_dirent {
 	compat_ulong_t	d_ino;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v7 3/3] io_uring: add support for getdents64
  2021-12-22 21:07 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function Stefan Roesch
  2021-12-22 21:07 ` [PATCH v7 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
@ 2021-12-22 21:07 ` Stefan Roesch
  2 siblings, 0 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-12-22 21:07 UTC (permalink / raw)
  To: linux-nfs; +Cc: shr, Pavel Begunkov

This adds support for getdents64 to io_uring.

Signed-off-by: Stefan Roesch <shr@fb.com>
Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
---
 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 5092dfe56da6..c8258c784116 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -693,6 +693,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;
 };
@@ -858,6 +865,7 @@ struct io_kiocb {
 		struct io_mkdir		mkdir;
 		struct io_symlink	symlink;
 		struct io_hardlink	hardlink;
+		struct io_getdents	getdents;
 	};
 
 	u8				opcode;
@@ -1107,6 +1115,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() */
@@ -4068,6 +4079,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)
 {
@@ -6574,6 +6621,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",
@@ -6857,6 +6906,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 v7 1/3] add offset parameter to iterate_dir function
  2021-12-22 21:07 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function Stefan Roesch
@ 2021-12-24 17:25   ` Chuck Lever III
  0 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever III @ 2021-12-24 17:25 UTC (permalink / raw)
  To: Stefan Roesch; +Cc: Linux NFS Mailing List


> On Dec 22, 2021, at 4:07 PM, Stefan Roesch <shr@fb.com> wrote:
> 
> This change adds the offset parameter to the iterate_dir
> function. The offset paramater allows the caller to specify
> the offset position.
> 
> This change is required to support getdents in io_uring.
> 
> Signed-off-by: Stefan Roesch <shr@fb.com>
> ---
> arch/alpha/kernel/osf_sys.c |  2 +-
> fs/ecryptfs/file.c          |  2 +-
> fs/exportfs/expfs.c         |  2 +-
> fs/ksmbd/smb2pdu.c          |  3 ++-
> fs/ksmbd/vfs.c              |  4 ++--
> fs/nfsd/nfs4recover.c       |  2 +-
> fs/nfsd/vfs.c               |  2 +-
> fs/overlayfs/readdir.c      |  6 +++---
> fs/readdir.c                | 28 ++++++++++++++++++----------
> include/linux/fs.h          |  2 +-
> 10 files changed, 31 insertions(+), 22 deletions(-)

Thanks for posting. The nfsd changes seem sensible to me.

Acked-by: Chuck Lever <chuck.lever@oracle.com>


> diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
> index 8bbeebb73cf0..cf68c459bca6 100644
> --- a/arch/alpha/kernel/osf_sys.c
> +++ b/arch/alpha/kernel/osf_sys.c
> @@ -162,7 +162,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
> 	if (!arg.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(arg.file, &buf.ctx);
> +	error = iterate_dir(arg.file, &buf.ctx, &arg.file->f_pos);
> 	if (error >= 0)
> 		error = buf.error;
> 	if (count != buf.count)
> diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
> index 18d5b91cb573..b68f1945e615 100644
> --- a/fs/ecryptfs/file.c
> +++ b/fs/ecryptfs/file.c
> @@ -109,7 +109,7 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
> 		.sb = inode->i_sb,
> 	};
> 	lower_file = ecryptfs_file_to_lower(file);
> -	rc = iterate_dir(lower_file, &buf.ctx);
> +	rc = iterate_dir(lower_file, &buf.ctx, &lower_file->f_pos);
> 	ctx->pos = buf.ctx.pos;
> 	if (rc < 0)
> 		goto out;
> diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
> index 0106eba46d5a..654e2d4b1d4f 100644
> --- a/fs/exportfs/expfs.c
> +++ b/fs/exportfs/expfs.c
> @@ -323,7 +323,7 @@ static int get_name(const struct path *path, char *name, struct dentry *child)
> 	while (1) {
> 		int old_seq = buffer.sequence;
> 
> -		error = iterate_dir(file, &buffer.ctx);
> +		error = iterate_dir(file, &buffer.ctx, &file->f_pos);
> 		if (buffer.found) {
> 			error = 0;
> 			break;
> diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
> index 49c9da37315c..fd4cb995d06d 100644
> --- a/fs/ksmbd/smb2pdu.c
> +++ b/fs/ksmbd/smb2pdu.c
> @@ -3925,7 +3925,8 @@ int smb2_query_dir(struct ksmbd_work *work)
> 	dir_fp->readdir_data.private		= &query_dir_private;
> 	set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
> 
> -	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
> +	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx,
> +			&dir_fp->filp->f_pos);
> 	if (rc == 0)
> 		restart_ctx(&dir_fp->readdir_data.ctx);
> 	if (rc == -ENOSPC)
> diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
> index 19d36393974c..5b8e23d3c846 100644
> --- a/fs/ksmbd/vfs.c
> +++ b/fs/ksmbd/vfs.c
> @@ -1136,7 +1136,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
> 	set_ctx_actor(&readdir_data.ctx, __dir_empty);
> 	readdir_data.dirent_count = 0;
> 
> -	err = iterate_dir(fp->filp, &readdir_data.ctx);
> +	err = iterate_dir(fp->filp, &readdir_data.ctx, &fp->filp->f_pos);
> 	if (readdir_data.dirent_count > 2)
> 		err = -ENOTEMPTY;
> 	else
> @@ -1186,7 +1186,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen)
> 	if (IS_ERR(dfilp))
> 		return PTR_ERR(dfilp);
> 
> -	ret = iterate_dir(dfilp, &readdir_data.ctx);
> +	ret = iterate_dir(dfilp, &readdir_data.ctx, &dfilp->f_pos);
> 	if (readdir_data.dirent_count > 0)
> 		ret = 0;
> 	fput(dfilp);
> diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
> index 6fedc49726bf..79a2799891e4 100644
> --- a/fs/nfsd/nfs4recover.c
> +++ b/fs/nfsd/nfs4recover.c
> @@ -307,7 +307,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
> 		return status;
> 	}
> 
> -	status = iterate_dir(nn->rec_file, &ctx.ctx);
> +	status = iterate_dir(nn->rec_file, &ctx.ctx, &nn->rec_file->f_pos);
> 	inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
> 
> 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index c99857689e2c..085864c25318 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1980,7 +1980,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
> 		buf.used = 0;
> 		buf.full = 0;
> 
> -		host_err = iterate_dir(file, &buf.ctx);
> +		host_err = iterate_dir(file, &buf.ctx, &file->f_pos);
> 		if (buf.full)
> 			host_err = 0;
> 
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index 150fdf3bc68d..52167ff9e513 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -306,7 +306,7 @@ static inline int ovl_dir_read(struct path *realpath,
> 	do {
> 		rdd->count = 0;
> 		rdd->err = 0;
> -		err = iterate_dir(realfile, &rdd->ctx);
> +		err = iterate_dir(realfile, &rdd->ctx, &realfile->f_pos);
> 		if (err >= 0)
> 			err = rdd->err;
> 	} while (!err && rdd->count);
> @@ -722,7 +722,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
> 			return PTR_ERR(rdt.cache);
> 	}
> 
> -	err = iterate_dir(od->realfile, &rdt.ctx);
> +	err = iterate_dir(od->realfile, &rdt.ctx, &od->realfile->f_pos);
> 	ctx->pos = rdt.ctx.pos;
> 
> 	return err;
> @@ -753,7 +753,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
> 		      OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
> 			err = ovl_iterate_real(file, ctx);
> 		} else {
> -			err = iterate_dir(od->realfile, ctx);
> +			err = iterate_dir(od->realfile, ctx, &od->realfile->f_pos);
> 		}
> 		goto out;
> 	}
> diff --git a/fs/readdir.c b/fs/readdir.c
> index 09e8ed7d4161..c1e6612e0f47 100644
> --- a/fs/readdir.c
> +++ b/fs/readdir.c
> @@ -36,8 +36,13 @@
> 	unsafe_copy_to_user(dst, src, len, label);		\
> } while (0)
> 
> -
> -int iterate_dir(struct file *file, struct dir_context *ctx)
> +/**
> + * iterate_dir - iterate over directory
> + * @file    : pointer to file struct of directory
> + * @ctx     : pointer to directory ctx structure
> + * @pos     : file offset
> + */
> +int iterate_dir(struct file *file, struct dir_context *ctx, loff_t *pos)
> {
> 	struct inode *inode = file_inode(file);
> 	bool shared = false;
> @@ -60,12 +65,15 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
> 
> 	res = -ENOENT;
> 	if (!IS_DEADDIR(inode)) {
> -		ctx->pos = file->f_pos;
> +		ctx->pos = *pos;
> +
> 		if (shared)
> 			res = file->f_op->iterate_shared(file, ctx);
> 		else
> 			res = file->f_op->iterate(file, ctx);
> -		file->f_pos = ctx->pos;
> +
> +		*pos = ctx->pos;
> +
> 		fsnotify_access(file);
> 		file_accessed(file);
> 	}
> @@ -190,7 +198,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
> 	if (!f.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(f.file, &buf.ctx);
> +	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
> 	if (buf.result)
> 		error = buf.result;
> 
> @@ -283,7 +291,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
> 	if (!f.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(f.file, &buf.ctx);
> +	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
> 	if (error >= 0)
> 		error = buf.error;
> 	if (buf.prev_reclen) {
> @@ -366,7 +374,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
> 	if (!f.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(f.file, &buf.ctx);
> +	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
> 	if (error >= 0)
> 		error = buf.error;
> 	if (buf.prev_reclen) {
> @@ -379,7 +387,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
> 		else
> 			error = count - buf.count;
> 	}
> -	fdput_pos(f);
> +
> 	return error;
> }
> 
> @@ -448,7 +456,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
> 	if (!f.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(f.file, &buf.ctx);
> +	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
> 	if (buf.result)
> 		error = buf.result;
> 
> @@ -534,7 +542,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
> 	if (!f.file)
> 		return -EBADF;
> 
> -	error = iterate_dir(f.file, &buf.ctx);
> +	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
> 	if (error >= 0)
> 		error = buf.error;
> 	if (buf.prev_reclen) {
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6b8dc1a78df6..e1becbe86b07 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -3340,7 +3340,7 @@ const char *simple_get_link(struct dentry *, struct inode *,
> 			    struct delayed_call *);
> extern const struct inode_operations simple_symlink_inode_operations;
> 
> -extern int iterate_dir(struct file *, struct dir_context *);
> +extern int iterate_dir(struct file *, struct dir_context *, loff_t *pos);
> 
> int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
> 		int flags);
> -- 
> 2.30.2
> 

--
Chuck Lever




^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v7 1/3] fs: add offset parameter to iterate_dir function
  2021-12-21 16:40 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
@ 2021-12-21 16:40 ` Stefan Roesch
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Roesch @ 2021-12-21 16:40 UTC (permalink / raw)
  To: io-uring, linux-fsdevel; +Cc: torvalds, shr

This change adds the offset parameter to the iterate_dir
function. The offset paramater allows the caller to specify
the offset position.

This change is required to support getdents in io_uring.

Signed-off-by: Stefan Roesch <shr@fb.com>
---
 arch/alpha/kernel/osf_sys.c |  2 +-
 fs/ecryptfs/file.c          |  2 +-
 fs/exportfs/expfs.c         |  2 +-
 fs/ksmbd/smb2pdu.c          |  3 ++-
 fs/ksmbd/vfs.c              |  4 ++--
 fs/nfsd/nfs4recover.c       |  2 +-
 fs/nfsd/vfs.c               |  2 +-
 fs/overlayfs/readdir.c      |  6 +++---
 fs/readdir.c                | 28 ++++++++++++++++++----------
 include/linux/fs.h          |  2 +-
 10 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 8bbeebb73cf0..cf68c459bca6 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -162,7 +162,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
 	if (!arg.file)
 		return -EBADF;
 
-	error = iterate_dir(arg.file, &buf.ctx);
+	error = iterate_dir(arg.file, &buf.ctx, &arg.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (count != buf.count)
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 18d5b91cb573..b68f1945e615 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -109,7 +109,7 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
 		.sb = inode->i_sb,
 	};
 	lower_file = ecryptfs_file_to_lower(file);
-	rc = iterate_dir(lower_file, &buf.ctx);
+	rc = iterate_dir(lower_file, &buf.ctx, &lower_file->f_pos);
 	ctx->pos = buf.ctx.pos;
 	if (rc < 0)
 		goto out;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 0106eba46d5a..654e2d4b1d4f 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -323,7 +323,7 @@ static int get_name(const struct path *path, char *name, struct dentry *child)
 	while (1) {
 		int old_seq = buffer.sequence;
 
-		error = iterate_dir(file, &buffer.ctx);
+		error = iterate_dir(file, &buffer.ctx, &file->f_pos);
 		if (buffer.found) {
 			error = 0;
 			break;
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 49c9da37315c..fd4cb995d06d 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -3925,7 +3925,8 @@ int smb2_query_dir(struct ksmbd_work *work)
 	dir_fp->readdir_data.private		= &query_dir_private;
 	set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
 
-	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
+	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx,
+			&dir_fp->filp->f_pos);
 	if (rc == 0)
 		restart_ctx(&dir_fp->readdir_data.ctx);
 	if (rc == -ENOSPC)
diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c
index 19d36393974c..5b8e23d3c846 100644
--- a/fs/ksmbd/vfs.c
+++ b/fs/ksmbd/vfs.c
@@ -1136,7 +1136,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
 	set_ctx_actor(&readdir_data.ctx, __dir_empty);
 	readdir_data.dirent_count = 0;
 
-	err = iterate_dir(fp->filp, &readdir_data.ctx);
+	err = iterate_dir(fp->filp, &readdir_data.ctx, &fp->filp->f_pos);
 	if (readdir_data.dirent_count > 2)
 		err = -ENOTEMPTY;
 	else
@@ -1186,7 +1186,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen)
 	if (IS_ERR(dfilp))
 		return PTR_ERR(dfilp);
 
-	ret = iterate_dir(dfilp, &readdir_data.ctx);
+	ret = iterate_dir(dfilp, &readdir_data.ctx, &dfilp->f_pos);
 	if (readdir_data.dirent_count > 0)
 		ret = 0;
 	fput(dfilp);
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 6fedc49726bf..79a2799891e4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -307,7 +307,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 		return status;
 	}
 
-	status = iterate_dir(nn->rec_file, &ctx.ctx);
+	status = iterate_dir(nn->rec_file, &ctx.ctx, &nn->rec_file->f_pos);
 	inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c99857689e2c..085864c25318 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1980,7 +1980,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
 		buf.used = 0;
 		buf.full = 0;
 
-		host_err = iterate_dir(file, &buf.ctx);
+		host_err = iterate_dir(file, &buf.ctx, &file->f_pos);
 		if (buf.full)
 			host_err = 0;
 
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 150fdf3bc68d..52167ff9e513 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -306,7 +306,7 @@ static inline int ovl_dir_read(struct path *realpath,
 	do {
 		rdd->count = 0;
 		rdd->err = 0;
-		err = iterate_dir(realfile, &rdd->ctx);
+		err = iterate_dir(realfile, &rdd->ctx, &realfile->f_pos);
 		if (err >= 0)
 			err = rdd->err;
 	} while (!err && rdd->count);
@@ -722,7 +722,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
 			return PTR_ERR(rdt.cache);
 	}
 
-	err = iterate_dir(od->realfile, &rdt.ctx);
+	err = iterate_dir(od->realfile, &rdt.ctx, &od->realfile->f_pos);
 	ctx->pos = rdt.ctx.pos;
 
 	return err;
@@ -753,7 +753,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
 		      OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
 			err = ovl_iterate_real(file, ctx);
 		} else {
-			err = iterate_dir(od->realfile, ctx);
+			err = iterate_dir(od->realfile, ctx, &od->realfile->f_pos);
 		}
 		goto out;
 	}
diff --git a/fs/readdir.c b/fs/readdir.c
index 09e8ed7d4161..c1e6612e0f47 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -36,8 +36,13 @@
 	unsafe_copy_to_user(dst, src, len, label);		\
 } while (0)
 
-
-int iterate_dir(struct file *file, struct dir_context *ctx)
+/**
+ * iterate_dir - iterate over directory
+ * @file    : pointer to file struct of directory
+ * @ctx     : pointer to directory ctx structure
+ * @pos     : file offset
+ */
+int iterate_dir(struct file *file, struct dir_context *ctx, loff_t *pos)
 {
 	struct inode *inode = file_inode(file);
 	bool shared = false;
@@ -60,12 +65,15 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
 
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
-		ctx->pos = file->f_pos;
+		ctx->pos = *pos;
+
 		if (shared)
 			res = file->f_op->iterate_shared(file, ctx);
 		else
 			res = file->f_op->iterate(file, ctx);
-		file->f_pos = ctx->pos;
+
+		*pos = ctx->pos;
+
 		fsnotify_access(file);
 		file_accessed(file);
 	}
@@ -190,7 +198,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (buf.result)
 		error = buf.result;
 
@@ -283,7 +291,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
@@ -366,7 +374,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
@@ -379,7 +387,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
 		else
 			error = count - buf.count;
 	}
-	fdput_pos(f);
+
 	return error;
 }
 
@@ -448,7 +456,7 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (buf.result)
 		error = buf.result;
 
@@ -534,7 +542,7 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
 	if (!f.file)
 		return -EBADF;
 
-	error = iterate_dir(f.file, &buf.ctx);
+	error = iterate_dir(f.file, &buf.ctx, &f.file->f_pos);
 	if (error >= 0)
 		error = buf.error;
 	if (buf.prev_reclen) {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6b8dc1a78df6..e1becbe86b07 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3340,7 +3340,7 @@ const char *simple_get_link(struct dentry *, struct inode *,
 			    struct delayed_call *);
 extern const struct inode_operations simple_symlink_inode_operations;
 
-extern int iterate_dir(struct file *, struct dir_context *);
+extern int iterate_dir(struct file *, struct dir_context *, loff_t *pos);
 
 int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 		int flags);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-12-24 17:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-22 21:07 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
2021-12-22 21:07 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function Stefan Roesch
2021-12-24 17:25   ` [PATCH v7 1/3] " Chuck Lever III
2021-12-22 21:07 ` [PATCH v7 2/3] fs: split off vfs_getdents function of getdents64 syscall Stefan Roesch
2021-12-22 21:07 ` [PATCH v7 3/3] io_uring: add support for getdents64 Stefan Roesch
  -- strict thread matches above, loose matches on Subject: below --
2021-12-21 16:40 [PATCH v7 0/3] io_uring: add getdents64 support Stefan Roesch
2021-12-21 16:40 ` [PATCH v7 1/3] fs: add offset parameter to iterate_dir function 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.