On Tue, 2024-10-08 at 15:11 +0200, Amir Goldstein wrote: > On Tue, Oct 8, 2024 at 1:07 PM Jeff Layton <jlayton@xxxxxxxxxx> wrote: > > > > On Mon, 2024-10-07 at 17:26 +0200, Amir Goldstein wrote: > > > On Wed, Sep 25, 2024 at 11:14 AM Christian Brauner <brauner@xxxxxxxxxx> wrote: > > > > > > > > > open_by_handle_at(2) does not have AT_ flags argument, but also, I find > > > > > it more useful API that encoding a connectable file handle can mandate > > > > > the resolving of a connected fd, without having to opt-in for a > > > > > connected fd independently. > > > > > > > > This seems the best option to me too if this api is to be added. > > > > > > Thanks. > > > > > > Jeff, Chuck, > > > > > > Any thoughts on this? > > > > > > > Sorry for the delay. I think encoding the new flag into the fh itself > > is a reasonable approach. > > > > Adding Jan. > Sorry I forgot to CC you on the patches, but struct file_handle is officially > a part of fanotify ABI, so your ACK is also needed on this change. > > > I'm less thrilled with using bitfields for this, just because I have a > > general dislike of them, and they aren't implemented the same way on > > all arches. Would it break ABI if we just turned the handle_type int > > into two uint16_t's instead? > > I think it will because this will not be backward compat on LE arch: > > struct file_handle { > __u32 handle_bytes; > - int handle_type; > + __u16 handle_type; > + __u16 handle_flags; > /* file identifier */ > unsigned char f_handle[] __counted_by(handle_bytes); > }; > Ok, good point. > But I can also do without the bitfileds, maybe it's better this way. > See diff from v2: > > diff --git a/fs/fhandle.c b/fs/fhandle.c > index 4ce4ffddec62..64d44fc61d43 100644 > --- a/fs/fhandle.c > +++ b/fs/fhandle.c > @@ -87,9 +87,9 @@ static long do_sys_name_to_handle(const struct path *path, > * decoding connectable non-directory file handles. > */ > if (fh_flags & EXPORT_FH_CONNECTABLE) { > + handle->handle_type |= FILEID_IS_CONNECTABLE; > if (d_is_dir(path->dentry)) > - fh_flags |= EXPORT_FH_DIR_ONLY; > - handle->handle_flags = fh_flags; > + fh_flags |= FILEID_IS_DIR; > } > retval = 0; > } > @@ -352,7 +352,7 @@ static int handle_to_path(int mountdirfd, struct > file_handle __user *ufh, > retval = -EINVAL; > goto out_path; > } > - if (f_handle.handle_flags & ~EXPORT_FH_USER_FLAGS) { > + if (!FILEID_USER_TYPE_IS_VALID(f_handle.handle_type)) { > retval = -EINVAL; > goto out_path; > } > @@ -377,10 +377,14 @@ static int handle_to_path(int mountdirfd, struct > file_handle __user *ufh, > * are decoding an fd with connected path, which is accessible from > * the mount fd path. > */ > - ctx.fh_flags |= f_handle.handle_flags; > - if (ctx.fh_flags & EXPORT_FH_CONNECTABLE) > + if (f_handle.handle_type & FILEID_IS_CONNECTABLE) { > + ctx.fh_flags |= EXPORT_FH_CONNECTABLE; > ctx.flags |= HANDLE_CHECK_SUBTREE; > - > + if (f_handle.handle_type & FILEID_IS_DIR) > + ctx.fh_flags |= EXPORT_FH_DIR_ONLY; > + } > + /* Filesystem code should not be exposed to user flags */ > + handle->handle_type &= ~FILEID_USER_FLAGS_MASK; > retval = do_handle_to_path(handle, path, &ctx); > > out_handle: > diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h > index 96b62e502f71..3e60bac74fa3 100644 > --- a/include/linux/exportfs.h > +++ b/include/linux/exportfs.h > @@ -159,8 +159,17 @@ struct fid { > #define EXPORT_FH_CONNECTABLE 0x1 /* Encode file handle with parent */ > #define EXPORT_FH_FID 0x2 /* File handle may be non-decodeable */ > #define EXPORT_FH_DIR_ONLY 0x4 /* Only decode file handle for a > directory */ > -/* Flags allowed in encoded handle_flags that is exported to user */ > -#define EXPORT_FH_USER_FLAGS (EXPORT_FH_CONNECTABLE | EXPORT_FH_DIR_ONLY) Maybe add a nice comment here about how the handle_type word is partitioned? > + > +/* Flags supported in encoded handle_type that is exported to user */ > +#define FILEID_USER_FLAGS_MASK 0xffff0000 > +#define FILEID_USER_FLAGS(type) ((type) & FILEID_USER_FLAGS_MASK) > + > +#define FILEID_IS_CONNECTABLE 0x10000 > +#define FILEID_IS_DIR 0x40000 > +#define FILEID_VALID_USER_FLAGS (FILEID_IS_CONNECTABLE | FILEID_IS_DIR) > + > +#define FILEID_USER_TYPE_IS_VALID(type) \ > + (FILEID_USER_FLAGS(type) & ~FILEID_VALID_USER_FLAGS) > > /** > * struct export_operations - for nfsd to communicate with file systems > diff --git a/include/linux/fs.h b/include/linux/fs.h > index cca7e575d1f8..6329fec40872 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -1071,8 +1071,7 @@ struct file { > > struct file_handle { > __u32 handle_bytes; > - int handle_type:16; > - int handle_flags:16; > + int handle_type; > /* file identifier */ > unsigned char f_handle[] __counted_by(handle_bytes); > }; I like that better than bitfields, fwiw. -- Jeff Layton <jlayton@xxxxxxxxxx>