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 |
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.
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
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.
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?
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 --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 */
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(-)