On Fri, Aug 15, 2025 at 1:51 AM Thomas Bertschinger <tahbertschinger@xxxxxxxxx> wrote: > > Add support for name_to_handle_at(2) to io_uring. > > Like openat*(), this tries to do a non-blocking lookup first and resorts > to async lookup when that fails. > > This uses sqe->addr for the path, ->addr2 for the file handle which is > filled in by the kernel, and ->addr3 for the mouint_id which is filled > in by the kernel. > > Signed-off-by: Thomas Bertschinger <tahbertschinger@xxxxxxxxx> > --- > include/uapi/linux/io_uring.h | 1 + > io_uring/opdef.c | 7 ++++++ > io_uring/openclose.c | 43 +++++++++++++++++++++++++++++++++++ > io_uring/openclose.h | 3 +++ > 4 files changed, 54 insertions(+) > > diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h > index 6957dc539d83..596bae788b48 100644 > --- a/include/uapi/linux/io_uring.h > +++ b/include/uapi/linux/io_uring.h > @@ -289,6 +289,7 @@ enum io_uring_op { > IORING_OP_READV_FIXED, > IORING_OP_WRITEV_FIXED, > IORING_OP_PIPE, > + IORING_OP_NAME_TO_HANDLE_AT, > > /* this goes last, obviously */ > IORING_OP_LAST, > diff --git a/io_uring/opdef.c b/io_uring/opdef.c > index 9568785810d9..ff2672bbd583 100644 > --- a/io_uring/opdef.c > +++ b/io_uring/opdef.c > @@ -574,6 +574,10 @@ const struct io_issue_def io_issue_defs[] = { > .prep = io_pipe_prep, > .issue = io_pipe, > }, > + [IORING_OP_NAME_TO_HANDLE_AT] = { > + .prep = io_name_to_handle_at_prep, > + .issue = io_name_to_handle_at, > + }, > }; > > const struct io_cold_def io_cold_defs[] = { > @@ -824,6 +828,9 @@ const struct io_cold_def io_cold_defs[] = { > [IORING_OP_PIPE] = { > .name = "PIPE", > }, > + [IORING_OP_NAME_TO_HANDLE_AT] = { > + .name = "NAME_TO_HANDLE_AT", > + }, > }; > > const char *io_uring_get_opcode(u8 opcode) > diff --git a/io_uring/openclose.c b/io_uring/openclose.c > index d70700e5cef8..f15a9307f811 100644 > --- a/io_uring/openclose.c > +++ b/io_uring/openclose.c > @@ -27,6 +27,15 @@ struct io_open { > unsigned long nofile; > }; > > +struct io_name_to_handle { > + struct file *file; > + int dfd; > + int open_flag; These are not open_flags, there are handle_flags (e.g. AT_HANDLE_FID) > + struct file_handle __user *ufh; > + char __user *path; > + void __user *mount_id; > +}; > + > struct io_close { > struct file *file; > int fd; > @@ -187,6 +196,40 @@ void io_open_cleanup(struct io_kiocb *req) > putname(open->filename); > } > > +int io_name_to_handle_at_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) > +{ > + struct io_name_to_handle *nh = io_kiocb_to_cmd(req, struct io_name_to_handle); > + > + nh->dfd = READ_ONCE(sqe->fd); > + nh->open_flag = READ_ONCE(sqe->open_flags); Please also create union member sqe->handle_flags or name_to_handle_flags. Thanks, Amir.