io-uring.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/1] io-uring: Make statx api stable
@ 2022-02-25 18:53 Stefan Roesch
  2022-02-25 18:53 ` [PATCH v4 1/1] io-uring: Make statx API stable Stefan Roesch
  2022-02-25 20:30 ` [PATCH v4 0/1] io-uring: Make statx api stable Jens Axboe
  0 siblings, 2 replies; 4+ messages in thread
From: Stefan Roesch @ 2022-02-25 18:53 UTC (permalink / raw)
  To: io-uring, linux-fsdevel, kernel-team; +Cc: viro, shr, rostedt, m.szyprowski

One of the key architectual tenets of io-uring is to keep the
parameters for io-uring stable. After the call has been submitted,
its value can be changed.  Unfortunaltely this is not the case for
the current statx implementation.

Patch:
 Part 1: fs: replace const char* parameter in vfs_statx and do_statx with
          struct filename
   Create filename object outside of do_statx and vfs_statx, so io-uring
   can create the filename object during the prepare phase

 Part 2: io-uring: Copy path name during prepare stage for statx
   Create and store filename object during prepare phase


There is also a patch for the liburing libray to add a new test case. This
patch makes sure that the api is stable.
  "liburing: add test for stable statx api"

The patch has been tested with the liburing test suite and fstests.


Changes:
V2: don't check name in vfs_fstatat
V3: don't check name in statx syscall
V4: - incorporate Steven Rostedt's fix
    - Merge both patches to avoid bisect problem
      (the io-uring changes have a dependency on the parameter change in
       the fs layer)


Stefan Roesch (1):
  io-uring: Make statx API stable

 fs/internal.h |  4 +++-
 fs/io_uring.c | 22 ++++++++++++++++++++--
 fs/stat.c     | 49 +++++++++++++++++++++++++++++++++++--------------
 3 files changed, 58 insertions(+), 17 deletions(-)


base-commit: 5c1ee569660d4a205dced9cb4d0306b907fb7599
-- 
2.30.2


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

* [PATCH v4 1/1] io-uring: Make statx API stable
  2022-02-25 18:53 [PATCH v4 0/1] io-uring: Make statx api stable Stefan Roesch
@ 2022-02-25 18:53 ` Stefan Roesch
  2022-02-26 20:01   ` Luis Chamberlain
  2022-02-25 20:30 ` [PATCH v4 0/1] io-uring: Make statx api stable Jens Axboe
  1 sibling, 1 reply; 4+ messages in thread
From: Stefan Roesch @ 2022-02-25 18:53 UTC (permalink / raw)
  To: io-uring, linux-fsdevel, kernel-team; +Cc: viro, shr, rostedt, m.szyprowski

One of the key architectual tenets is to keep the parameters for
io-uring stable. After the call has been submitted, its value can
be changed. Unfortunaltely this is not the case for the current statx
implementation.

IO-Uring change:
This changes replaces the const char * filename pointer in the io_statx
structure with a struct filename *. In addition it also creates the
filename object during the prepare phase.

With this change, the opcode also needs to invoke cleanup, so the
filename object gets freed after processing the request.

fs change:
This replaces the const char* __user filename parameter in the two
functions do_statx and vfs_statx with a struct filename *. In addition
to be able to correctly construct a filename object a new helper
function getname_statx_lookup_flags is introduced. The function makes
sure that do_statx and vfs_statx is invoked with the correct lookup flags.

Signed-off-by: Stefan Roesch <shr@fb.com>
---
 fs/internal.h |  4 +++-
 fs/io_uring.c | 22 ++++++++++++++++++++--
 fs/stat.c     | 49 +++++++++++++++++++++++++++++++++++--------------
 3 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index 8590c973c2f4..56c0477f4215 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -184,7 +184,9 @@ int sb_init_dio_done_wq(struct super_block *sb);
 /*
  * fs/stat.c:
  */
-int do_statx(int dfd, const char __user *filename, unsigned flags,
+
+int getname_statx_lookup_flags(int flags);
+int do_statx(int dfd, struct filename *filename, unsigned int flags,
 	     unsigned int mask, struct statx __user *buffer);
 
 /*
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 77b9c7e4793b..28b09b163df1 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -642,7 +642,7 @@ struct io_statx {
 	int				dfd;
 	unsigned int			mask;
 	unsigned int			flags;
-	const char __user		*filename;
+	struct filename			*filename;
 	struct statx __user		*buffer;
 };
 
@@ -4721,6 +4721,8 @@ static int io_fadvise(struct io_kiocb *req, unsigned int issue_flags)
 
 static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
+	const char __user *path;
+
 	if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
 		return -EINVAL;
 	if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
@@ -4730,10 +4732,22 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 
 	req->statx.dfd = READ_ONCE(sqe->fd);
 	req->statx.mask = READ_ONCE(sqe->len);
-	req->statx.filename = u64_to_user_ptr(READ_ONCE(sqe->addr));
+	path = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
 	req->statx.flags = READ_ONCE(sqe->statx_flags);
 
+	req->statx.filename = getname_flags(path,
+					getname_statx_lookup_flags(req->statx.flags),
+					NULL);
+
+	if (IS_ERR(req->statx.filename)) {
+		int ret = PTR_ERR(req->statx.filename);
+
+		req->statx.filename = NULL;
+		return ret;
+	}
+
+	req->flags |= REQ_F_NEED_CLEANUP;
 	return 0;
 }
 
@@ -6708,6 +6722,10 @@ static void io_clean_op(struct io_kiocb *req)
 			putname(req->hardlink.oldpath);
 			putname(req->hardlink.newpath);
 			break;
+		case IORING_OP_STATX:
+			if (req->statx.filename)
+				putname(req->statx.filename);
+			break;
 		}
 	}
 	if ((req->flags & REQ_F_POLLED) && req->apoll) {
diff --git a/fs/stat.c b/fs/stat.c
index 28d2020ba1f4..7f734be0e57e 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -184,6 +184,20 @@ int vfs_fstat(int fd, struct kstat *stat)
 	return error;
 }
 
+int getname_statx_lookup_flags(int flags)
+{
+	int lookup_flags = 0;
+
+	if (!(flags & AT_SYMLINK_NOFOLLOW))
+		lookup_flags |= LOOKUP_FOLLOW;
+	if (!(flags & AT_NO_AUTOMOUNT))
+		lookup_flags |= LOOKUP_AUTOMOUNT;
+	if (flags & AT_EMPTY_PATH)
+		lookup_flags |= LOOKUP_EMPTY;
+
+	return lookup_flags;
+}
+
 /**
  * vfs_statx - Get basic and extra attributes by filename
  * @dfd: A file descriptor representing the base dir for a relative filename
@@ -199,26 +213,19 @@ int vfs_fstat(int fd, struct kstat *stat)
  *
  * 0 will be returned on success, and a -ve error code if unsuccessful.
  */
-static int vfs_statx(int dfd, const char __user *filename, int flags,
+static int vfs_statx(int dfd, struct filename *filename, int flags,
 	      struct kstat *stat, u32 request_mask)
 {
 	struct path path;
-	unsigned lookup_flags = 0;
+	unsigned int lookup_flags = getname_statx_lookup_flags(flags);
 	int error;
 
 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
 		      AT_STATX_SYNC_TYPE))
 		return -EINVAL;
 
-	if (!(flags & AT_SYMLINK_NOFOLLOW))
-		lookup_flags |= LOOKUP_FOLLOW;
-	if (!(flags & AT_NO_AUTOMOUNT))
-		lookup_flags |= LOOKUP_AUTOMOUNT;
-	if (flags & AT_EMPTY_PATH)
-		lookup_flags |= LOOKUP_EMPTY;
-
 retry:
-	error = user_path_at(dfd, filename, lookup_flags, &path);
+	error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
 	if (error)
 		goto out;
 
@@ -240,8 +247,15 @@ static int vfs_statx(int dfd, const char __user *filename, int flags,
 int vfs_fstatat(int dfd, const char __user *filename,
 			      struct kstat *stat, int flags)
 {
-	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
-			 stat, STATX_BASIC_STATS);
+	int ret;
+	int statx_flags = flags | AT_NO_AUTOMOUNT;
+	struct filename *name;
+
+	name = getname_flags(filename, getname_statx_lookup_flags(statx_flags), NULL);
+	ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS);
+	putname(name);
+
+	return ret;
 }
 
 #ifdef __ARCH_WANT_OLD_STAT
@@ -602,7 +616,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
 	return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
-int do_statx(int dfd, const char __user *filename, unsigned flags,
+int do_statx(int dfd, struct filename *filename, unsigned int flags,
 	     unsigned int mask, struct statx __user *buffer)
 {
 	struct kstat stat;
@@ -636,7 +650,14 @@ SYSCALL_DEFINE5(statx,
 		unsigned int, mask,
 		struct statx __user *, buffer)
 {
-	return do_statx(dfd, filename, flags, mask, buffer);
+	int ret;
+	struct filename *name;
+
+	name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL);
+	ret = do_statx(dfd, name, flags, mask, buffer);
+	putname(name);
+
+	return ret;
 }
 
 #ifdef CONFIG_COMPAT
-- 
2.30.2


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

* Re: [PATCH v4 0/1] io-uring: Make statx api stable
  2022-02-25 18:53 [PATCH v4 0/1] io-uring: Make statx api stable Stefan Roesch
  2022-02-25 18:53 ` [PATCH v4 1/1] io-uring: Make statx API stable Stefan Roesch
@ 2022-02-25 20:30 ` Jens Axboe
  1 sibling, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2022-02-25 20:30 UTC (permalink / raw)
  To: io-uring, kernel-team, linux-fsdevel, Stefan Roesch
  Cc: m.szyprowski, viro, rostedt

On Fri, 25 Feb 2022 10:53:25 -0800, Stefan Roesch wrote:
> One of the key architectual tenets of io-uring is to keep the
> parameters for io-uring stable. After the call has been submitted,
> its value can be changed.  Unfortunaltely this is not the case for
> the current statx implementation.
> 
> Patch:
>  Part 1: fs: replace const char* parameter in vfs_statx and do_statx with
>           struct filename
>    Create filename object outside of do_statx and vfs_statx, so io-uring
>    can create the filename object during the prepare phase
> 
> [...]

Applied, thanks!

[1/1] io-uring: Make statx API stable
      commit: c22368edfa24ec033f9328b3328aaa0349c15e6c

Best regards,
-- 
Jens Axboe



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

* Re: [PATCH v4 1/1] io-uring: Make statx API stable
  2022-02-25 18:53 ` [PATCH v4 1/1] io-uring: Make statx API stable Stefan Roesch
@ 2022-02-26 20:01   ` Luis Chamberlain
  0 siblings, 0 replies; 4+ messages in thread
From: Luis Chamberlain @ 2022-02-26 20:01 UTC (permalink / raw)
  To: Stefan Roesch
  Cc: io-uring, linux-fsdevel, kernel-team, viro, rostedt, m.szyprowski

On Fri, Feb 25, 2022 at 10:53:26AM -0800, Stefan Roesch wrote:
> One of the key architectual tenets is to keep the parameters for
> io-uring stable. After the call has been submitted, its value can
> be changed. Unfortunaltely this is not the case for the current statx
> implementation.
> 
> IO-Uring change:
> This changes replaces the const char * filename pointer in the io_statx
> structure with a struct filename *. In addition it also creates the
> filename object during the prepare phase.
> 
> With this change, the opcode also needs to invoke cleanup, so the
> filename object gets freed after processing the request.
> 
> fs change:
> This replaces the const char* __user filename parameter in the two
> functions do_statx and vfs_statx with a struct filename *. In addition
> to be able to correctly construct a filename object a new helper
> function getname_statx_lookup_flags is introduced. The function makes
> sure that do_statx and vfs_statx is invoked with the correct lookup flags.
> 
> Signed-off-by: Stefan Roesch <shr@fb.com>

At least it doesn't break my KVM boots anymore:

Tested-by: Luis Chamberlain <mcgrof@kernel.org>

  Luis

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

end of thread, other threads:[~2022-02-26 20:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-25 18:53 [PATCH v4 0/1] io-uring: Make statx api stable Stefan Roesch
2022-02-25 18:53 ` [PATCH v4 1/1] io-uring: Make statx API stable Stefan Roesch
2022-02-26 20:01   ` Luis Chamberlain
2022-02-25 20:30 ` [PATCH v4 0/1] io-uring: Make statx api stable Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).