diff mbox series

[3/4] fs: expose LOOKUP_NONBLOCK through openat2() RESOLVE_NONBLOCK

Message ID 20201214191323.173773-4-axboe@kernel.dk (mailing list archive)
State New, archived
Headers show
Series fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK | expand

Commit Message

Jens Axboe Dec. 14, 2020, 7:13 p.m. UTC
Now that we support non-blocking path resolution internally, expose it
via openat2() in the struct open_how ->resolve flags. This allows
applications using openat2() to limit path resolution to the extent that
it is already cached.

If the lookup cannot be satisfied in a non-blocking manner, openat2(2)
will return -1/-EAGAIN.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/open.c                    | 6 ++++++
 include/linux/fcntl.h        | 2 +-
 include/uapi/linux/openat2.h | 4 ++++
 3 files changed, 11 insertions(+), 1 deletion(-)

Comments

Dave Chinner Dec. 15, 2020, 10:25 p.m. UTC | #1
On Mon, Dec 14, 2020 at 12:13:23PM -0700, Jens Axboe wrote:
> Now that we support non-blocking path resolution internally, expose it
> via openat2() in the struct open_how ->resolve flags. This allows
> applications using openat2() to limit path resolution to the extent that
> it is already cached.
> 
> If the lookup cannot be satisfied in a non-blocking manner, openat2(2)
> will return -1/-EAGAIN.
> 
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> ---
>  fs/open.c                    | 6 ++++++
>  include/linux/fcntl.h        | 2 +-
>  include/uapi/linux/openat2.h | 4 ++++

What text are you going to add to the man page to describe how this
flag behaves to developers?

Cheers,

Dave.
Linus Torvalds Dec. 15, 2020, 10:31 p.m. UTC | #2
On Tue, Dec 15, 2020 at 2:25 PM Dave Chinner <david@fromorbit.com> wrote:
>
> What text are you going to add to the man page to describe how this
> flag behaves to developers?

I think it was you or Jens who suggested renaming it to RESOLVE_CACHED
(and LOOKUP_CACHED), and I think that would be a good idea.

Make it explicit that this isn't primarily about avoiding blocking,
but about only doing name lookups that can be resolved directly from
the dcache.

Even in some other contexts, the traditional NONBLOCK naming isn't
necessarily about not blocking. Lots of operations tend to block even
for things that are requested to be "nonblocking", and in fact they
can even cause IO (ie a "nonblocking" read can and will cause IO when
it copies to user space, because _that_ part isn't nonblocking).

        Linus
Jens Axboe Dec. 15, 2020, 11:25 p.m. UTC | #3
On 12/15/20 3:31 PM, Linus Torvalds wrote:
> On Tue, Dec 15, 2020 at 2:25 PM Dave Chinner <david@fromorbit.com> wrote:
>>
>> What text are you going to add to the man page to describe how this
>> flag behaves to developers?
> 
> I think it was you or Jens who suggested renaming it to RESOLVE_CACHED
> (and LOOKUP_CACHED), and I think that would be a good idea.

Yeah that was me, and I think it helps both internally in terms of the
code being easier/better to read, and when exposed as a user API as
well. It makes it readily apparent what it does, which is much better
than requring lengthy descriptions of it...

I'll go ahead and make the edit.
Al Viro Dec. 16, 2020, 2:37 a.m. UTC | #4
On Mon, Dec 14, 2020 at 12:13:23PM -0700, Jens Axboe wrote:
> Now that we support non-blocking path resolution internally, expose it
> via openat2() in the struct open_how ->resolve flags. This allows
> applications using openat2() to limit path resolution to the extent that
> it is already cached.
> 
> If the lookup cannot be satisfied in a non-blocking manner, openat2(2)
> will return -1/-EAGAIN.
> 
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> ---
>  fs/open.c                    | 6 ++++++
>  include/linux/fcntl.h        | 2 +-
>  include/uapi/linux/openat2.h | 4 ++++
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/open.c b/fs/open.c
> index 9af548fb841b..a83434cfe01c 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -1087,6 +1087,12 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
>  		lookup_flags |= LOOKUP_BENEATH;
>  	if (how->resolve & RESOLVE_IN_ROOT)
>  		lookup_flags |= LOOKUP_IN_ROOT;
> +	if (how->resolve & RESOLVE_NONBLOCK) {
> +		/* Don't bother even trying for create/truncate open */
> +		if (flags & (O_TRUNC | O_CREAT))
> +			return -EAGAIN;

Why not O_TMPFILE here as well?
Linus Torvalds Dec. 16, 2020, 3:39 a.m. UTC | #5
On Tue, Dec 15, 2020 at 6:37 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> > +     if (how->resolve & RESOLVE_NONBLOCK) {
> > +             /* Don't bother even trying for create/truncate open */
> > +             if (flags & (O_TRUNC | O_CREAT))
> > +                     return -EAGAIN;
>
> Why not O_TMPFILE here as well?

Yup, I think that's just missing.

           Linus
diff mbox series

Patch

diff --git a/fs/open.c b/fs/open.c
index 9af548fb841b..a83434cfe01c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1087,6 +1087,12 @@  inline int build_open_flags(const struct open_how *how, struct open_flags *op)
 		lookup_flags |= LOOKUP_BENEATH;
 	if (how->resolve & RESOLVE_IN_ROOT)
 		lookup_flags |= LOOKUP_IN_ROOT;
+	if (how->resolve & RESOLVE_NONBLOCK) {
+		/* Don't bother even trying for create/truncate open */
+		if (flags & (O_TRUNC | O_CREAT))
+			return -EAGAIN;
+		lookup_flags |= LOOKUP_NONBLOCK;
+	}
 
 	op->lookup_flags = lookup_flags;
 	return 0;
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 921e750843e6..919a13c9317c 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -19,7 +19,7 @@ 
 /* List of all valid flags for the how->resolve argument: */
 #define VALID_RESOLVE_FLAGS \
 	(RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \
-	 RESOLVE_BENEATH | RESOLVE_IN_ROOT)
+	 RESOLVE_BENEATH | RESOLVE_IN_ROOT | RESOLVE_NONBLOCK)
 
 /* List of all open_how "versions". */
 #define OPEN_HOW_SIZE_VER0	24 /* sizeof first published struct */
diff --git a/include/uapi/linux/openat2.h b/include/uapi/linux/openat2.h
index 58b1eb711360..7bc1d0c35108 100644
--- a/include/uapi/linux/openat2.h
+++ b/include/uapi/linux/openat2.h
@@ -35,5 +35,9 @@  struct open_how {
 #define RESOLVE_IN_ROOT		0x10 /* Make all jumps to "/" and ".."
 					be scoped inside the dirfd
 					(similar to chroot(2)). */
+#define RESOLVE_NONBLOCK	0x20 /* Only complete if resolution can be
+					completed through cached lookup. May
+					return -EAGAIN if that's not
+					possible. */
 
 #endif /* _UAPI_LINUX_OPENAT2_H */