On Fri 29-11-24 14:38:04, Christian Brauner wrote: > This allows filesystems such as pidfs to provide their custom permission > checks. > > Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx> Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/fhandle.c | 21 +++++++-------------- > include/linux/exportfs.h | 17 ++++++++++++++++- > 2 files changed, 23 insertions(+), 15 deletions(-) > > diff --git a/fs/fhandle.c b/fs/fhandle.c > index 031ad5592a0beabcc299436f037ad5fe626332e6..23491094032ec037066a271873ea8ff794616bee 100644 > --- a/fs/fhandle.c > +++ b/fs/fhandle.c > @@ -187,17 +187,6 @@ static int get_path_from_fd(int fd, struct path *root) > return 0; > } > > -enum handle_to_path_flags { > - HANDLE_CHECK_PERMS = (1 << 0), > - HANDLE_CHECK_SUBTREE = (1 << 1), > -}; > - > -struct handle_to_path_ctx { > - struct path root; > - enum handle_to_path_flags flags; > - unsigned int fh_flags; > -}; > - > static int vfs_dentry_acceptable(void *context, struct dentry *dentry) > { > struct handle_to_path_ctx *ctx = context; > @@ -335,15 +324,19 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, > struct file_handle f_handle; > struct file_handle *handle = NULL; > struct handle_to_path_ctx ctx = {}; > + const struct export_operations *eops; > > retval = get_path_from_fd(mountdirfd, &ctx.root); > if (retval) > goto out_err; > > - if (!may_decode_fh(&ctx, o_flags)) { > - retval = -EPERM; > + eops = ctx.root.mnt->mnt_sb->s_export_op; > + if (eops && eops->permission) > + retval = eops->permission(&ctx, o_flags); > + else > + retval = may_decode_fh(&ctx, o_flags); > + if (retval) > goto out_path; > - } > > if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) { > retval = -EFAULT; > diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h > index c69b79b64466d5bc32ffe9b2796a388130fe72d8..a087606ace194ccc9d1250f990ce55627aaf8dc5 100644 > --- a/include/linux/exportfs.h > +++ b/include/linux/exportfs.h > @@ -3,6 +3,7 @@ > #define LINUX_EXPORTFS_H 1 > > #include <linux/types.h> > +#include <linux/path.h> > > struct dentry; > struct iattr; > @@ -10,7 +11,6 @@ struct inode; > struct iomap; > struct super_block; > struct vfsmount; > -struct path; > > /* limit the handle size to NFSv4 handle size now */ > #define MAX_HANDLE_SZ 128 > @@ -157,6 +157,17 @@ struct fid { > }; > }; > > +enum handle_to_path_flags { > + HANDLE_CHECK_PERMS = (1 << 0), > + HANDLE_CHECK_SUBTREE = (1 << 1), > +}; > + > +struct handle_to_path_ctx { > + struct path root; > + enum handle_to_path_flags flags; > + unsigned int fh_flags; > +}; > + > #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 */ > @@ -226,6 +237,9 @@ struct fid { > * is also a directory. In the event that it cannot be found, or storage > * space cannot be allocated, a %ERR_PTR should be returned. > * > + * permission: > + * Allow filesystems to specify a custom permission function. > + * > * open: > * Allow filesystems to specify a custom open function. > * > @@ -255,6 +269,7 @@ struct export_operations { > bool write, u32 *device_generation); > int (*commit_blocks)(struct inode *inode, struct iomap *iomaps, > int nr_iomaps, struct iattr *iattr); > + int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags); > struct file * (*open)(struct path *path, unsigned int oflags); > #define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */ > #define EXPORT_OP_NOSUBTREECHK (0x2) /* no subtree checking */ > > -- > 2.45.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR