Message ID | 20231018100000.2453965-3-amir73il@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Support more filesystems with FAN_REPORT_FID | expand |
On Wed, 2023-10-18 at 12:59 +0300, Amir Goldstein wrote: > The logic of whether filesystem can encode/decode file handles is open > coded in many places. > > In preparation to changing the logic, move the open coded logic into > inline helpers. > > Signed-off-by: Amir Goldstein <amir73il@gmail.com> > --- > fs/exportfs/expfs.c | 8 ++------ > fs/fhandle.c | 6 +----- > fs/nfsd/export.c | 3 +-- > fs/notify/fanotify/fanotify_user.c | 4 ++-- > fs/overlayfs/util.c | 2 +- > include/linux/exportfs.h | 27 +++++++++++++++++++++++++++ > 6 files changed, 34 insertions(+), 16 deletions(-) > > diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c > index c20704aa21b3..9ee205df8fa7 100644 > --- a/fs/exportfs/expfs.c > +++ b/fs/exportfs/expfs.c > @@ -396,11 +396,7 @@ int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, > { > const struct export_operations *nop = inode->i_sb->s_export_op; > > - /* > - * If a decodeable file handle was requested, we need to make sure that > - * filesystem can decode file handles. > - */ > - if (nop && !(flags & EXPORT_FH_FID) && !nop->fh_to_dentry) > + if (!exportfs_can_encode_fh(nop, flags)) > return -EOPNOTSUPP; > > if (nop && nop->encode_fh) > @@ -456,7 +452,7 @@ exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len, > /* > * Try to get any dentry for the given file handle from the filesystem. > */ > - if (!nop || !nop->fh_to_dentry) > + if (!exportfs_can_decode_fh(nop)) > return ERR_PTR(-ESTALE); > result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type); > if (IS_ERR_OR_NULL(result)) > diff --git a/fs/fhandle.c b/fs/fhandle.c > index 6ea8d35a9382..18b3ba8dc8ea 100644 > --- a/fs/fhandle.c > +++ b/fs/fhandle.c > @@ -26,12 +26,8 @@ static long do_sys_name_to_handle(const struct path *path, > /* > * We need to make sure whether the file system support decoding of > * the file handle if decodeable file handle was requested. > - * Otherwise, even empty export_operations are sufficient to opt-in > - * to encoding FIDs. > */ > - if (!path->dentry->d_sb->s_export_op || > - (!(fh_flags & EXPORT_FH_FID) && > - !path->dentry->d_sb->s_export_op->fh_to_dentry)) > + if (!exportfs_can_encode_fh(path->dentry->d_sb->s_export_op, fh_flags)) > return -EOPNOTSUPP; > > if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) > diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c > index 11a0eaa2f914..dc99dfc1d411 100644 > --- a/fs/nfsd/export.c > +++ b/fs/nfsd/export.c > @@ -421,8 +421,7 @@ static int check_export(struct path *path, int *flags, unsigned char *uuid) > return -EINVAL; > } > > - if (!inode->i_sb->s_export_op || > - !inode->i_sb->s_export_op->fh_to_dentry) { > + if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) { > dprintk("exp_export: export of invalid fs type.\n"); > return -EINVAL; > } > diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c > index 537c70beaad0..ce926eb9feea 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -1595,7 +1595,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) > * file handles so user can use name_to_handle_at() to compare fids > * reported with events to the file handle of watched objects. > */ > - if (!nop) > + if (!exportfs_can_encode_fid(nop)) > return -EOPNOTSUPP; > > /* > @@ -1603,7 +1603,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) > * supports decoding file handles, so user has a way to map back the > * reported fids to filesystem objects. > */ > - if (mark_type != FAN_MARK_INODE && !nop->fh_to_dentry) > + if (mark_type != FAN_MARK_INODE && !exportfs_can_decode_fh(nop)) > return -EOPNOTSUPP; > > return 0; > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c > index 89e0d60d35b6..f0a712214ec2 100644 > --- a/fs/overlayfs/util.c > +++ b/fs/overlayfs/util.c > @@ -55,7 +55,7 @@ int ovl_can_decode_fh(struct super_block *sb) > if (!capable(CAP_DAC_READ_SEARCH)) > return 0; > > - if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry) > + if (!exportfs_can_decode_fh(sb->s_export_op)) > return 0; > > return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN; > diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h > index 11fbd0ee1370..5b3c9f30b422 100644 > --- a/include/linux/exportfs.h > +++ b/include/linux/exportfs.h > @@ -233,6 +233,33 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, > extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, > int *max_len, int flags); > > +static inline bool exportfs_can_encode_fid(const struct export_operations *nop) > +{ > + return nop; > +} > + > +static inline bool exportfs_can_decode_fh(const struct export_operations *nop) > +{ > + return nop && nop->fh_to_dentry; > +} > + > +static inline bool exportfs_can_encode_fh(const struct export_operations *nop, > + int fh_flags) > +{ > + /* > + * If a non-decodeable file handle was requested, we only need to make > + * sure that filesystem can encode file handles. > + */ > + if (fh_flags & EXPORT_FH_FID) > + return exportfs_can_encode_fid(nop); > + > + /* > + * If a decodeable file handle was requested, we need to make sure that > + * filesystem can also decode file handles. > + */ > + return exportfs_can_decode_fh(nop); > +} > + > static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid, > int *max_len) > { Nice cleanup. Reviewed-by: Jeff Layton <jlayton@kernel.org>
On Wed 18-10-23 12:59:57, Amir Goldstein wrote: > The logic of whether filesystem can encode/decode file handles is open > coded in many places. > > In preparation to changing the logic, move the open coded logic into > inline helpers. > > Signed-off-by: Amir Goldstein <amir73il@gmail.com> Yeah, good cleanup. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > fs/exportfs/expfs.c | 8 ++------ > fs/fhandle.c | 6 +----- > fs/nfsd/export.c | 3 +-- > fs/notify/fanotify/fanotify_user.c | 4 ++-- > fs/overlayfs/util.c | 2 +- > include/linux/exportfs.h | 27 +++++++++++++++++++++++++++ > 6 files changed, 34 insertions(+), 16 deletions(-) > > diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c > index c20704aa21b3..9ee205df8fa7 100644 > --- a/fs/exportfs/expfs.c > +++ b/fs/exportfs/expfs.c > @@ -396,11 +396,7 @@ int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, > { > const struct export_operations *nop = inode->i_sb->s_export_op; > > - /* > - * If a decodeable file handle was requested, we need to make sure that > - * filesystem can decode file handles. > - */ > - if (nop && !(flags & EXPORT_FH_FID) && !nop->fh_to_dentry) > + if (!exportfs_can_encode_fh(nop, flags)) > return -EOPNOTSUPP; > > if (nop && nop->encode_fh) > @@ -456,7 +452,7 @@ exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len, > /* > * Try to get any dentry for the given file handle from the filesystem. > */ > - if (!nop || !nop->fh_to_dentry) > + if (!exportfs_can_decode_fh(nop)) > return ERR_PTR(-ESTALE); > result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type); > if (IS_ERR_OR_NULL(result)) > diff --git a/fs/fhandle.c b/fs/fhandle.c > index 6ea8d35a9382..18b3ba8dc8ea 100644 > --- a/fs/fhandle.c > +++ b/fs/fhandle.c > @@ -26,12 +26,8 @@ static long do_sys_name_to_handle(const struct path *path, > /* > * We need to make sure whether the file system support decoding of > * the file handle if decodeable file handle was requested. > - * Otherwise, even empty export_operations are sufficient to opt-in > - * to encoding FIDs. > */ > - if (!path->dentry->d_sb->s_export_op || > - (!(fh_flags & EXPORT_FH_FID) && > - !path->dentry->d_sb->s_export_op->fh_to_dentry)) > + if (!exportfs_can_encode_fh(path->dentry->d_sb->s_export_op, fh_flags)) > return -EOPNOTSUPP; > > if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) > diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c > index 11a0eaa2f914..dc99dfc1d411 100644 > --- a/fs/nfsd/export.c > +++ b/fs/nfsd/export.c > @@ -421,8 +421,7 @@ static int check_export(struct path *path, int *flags, unsigned char *uuid) > return -EINVAL; > } > > - if (!inode->i_sb->s_export_op || > - !inode->i_sb->s_export_op->fh_to_dentry) { > + if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) { > dprintk("exp_export: export of invalid fs type.\n"); > return -EINVAL; > } > diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c > index 537c70beaad0..ce926eb9feea 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -1595,7 +1595,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) > * file handles so user can use name_to_handle_at() to compare fids > * reported with events to the file handle of watched objects. > */ > - if (!nop) > + if (!exportfs_can_encode_fid(nop)) > return -EOPNOTSUPP; > > /* > @@ -1603,7 +1603,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) > * supports decoding file handles, so user has a way to map back the > * reported fids to filesystem objects. > */ > - if (mark_type != FAN_MARK_INODE && !nop->fh_to_dentry) > + if (mark_type != FAN_MARK_INODE && !exportfs_can_decode_fh(nop)) > return -EOPNOTSUPP; > > return 0; > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c > index 89e0d60d35b6..f0a712214ec2 100644 > --- a/fs/overlayfs/util.c > +++ b/fs/overlayfs/util.c > @@ -55,7 +55,7 @@ int ovl_can_decode_fh(struct super_block *sb) > if (!capable(CAP_DAC_READ_SEARCH)) > return 0; > > - if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry) > + if (!exportfs_can_decode_fh(sb->s_export_op)) > return 0; > > return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN; > diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h > index 11fbd0ee1370..5b3c9f30b422 100644 > --- a/include/linux/exportfs.h > +++ b/include/linux/exportfs.h > @@ -233,6 +233,33 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, > extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, > int *max_len, int flags); > > +static inline bool exportfs_can_encode_fid(const struct export_operations *nop) > +{ > + return nop; > +} > + > +static inline bool exportfs_can_decode_fh(const struct export_operations *nop) > +{ > + return nop && nop->fh_to_dentry; > +} > + > +static inline bool exportfs_can_encode_fh(const struct export_operations *nop, > + int fh_flags) > +{ > + /* > + * If a non-decodeable file handle was requested, we only need to make > + * sure that filesystem can encode file handles. > + */ > + if (fh_flags & EXPORT_FH_FID) > + return exportfs_can_encode_fid(nop); > + > + /* > + * If a decodeable file handle was requested, we need to make sure that > + * filesystem can also decode file handles. > + */ > + return exportfs_can_decode_fh(nop); > +} > + > static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid, > int *max_len) > { > -- > 2.34.1 >
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index c20704aa21b3..9ee205df8fa7 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -396,11 +396,7 @@ int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, { const struct export_operations *nop = inode->i_sb->s_export_op; - /* - * If a decodeable file handle was requested, we need to make sure that - * filesystem can decode file handles. - */ - if (nop && !(flags & EXPORT_FH_FID) && !nop->fh_to_dentry) + if (!exportfs_can_encode_fh(nop, flags)) return -EOPNOTSUPP; if (nop && nop->encode_fh) @@ -456,7 +452,7 @@ exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len, /* * Try to get any dentry for the given file handle from the filesystem. */ - if (!nop || !nop->fh_to_dentry) + if (!exportfs_can_decode_fh(nop)) return ERR_PTR(-ESTALE); result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type); if (IS_ERR_OR_NULL(result)) diff --git a/fs/fhandle.c b/fs/fhandle.c index 6ea8d35a9382..18b3ba8dc8ea 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -26,12 +26,8 @@ static long do_sys_name_to_handle(const struct path *path, /* * We need to make sure whether the file system support decoding of * the file handle if decodeable file handle was requested. - * Otherwise, even empty export_operations are sufficient to opt-in - * to encoding FIDs. */ - if (!path->dentry->d_sb->s_export_op || - (!(fh_flags & EXPORT_FH_FID) && - !path->dentry->d_sb->s_export_op->fh_to_dentry)) + if (!exportfs_can_encode_fh(path->dentry->d_sb->s_export_op, fh_flags)) return -EOPNOTSUPP; if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle))) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 11a0eaa2f914..dc99dfc1d411 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -421,8 +421,7 @@ static int check_export(struct path *path, int *flags, unsigned char *uuid) return -EINVAL; } - if (!inode->i_sb->s_export_op || - !inode->i_sb->s_export_op->fh_to_dentry) { + if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) { dprintk("exp_export: export of invalid fs type.\n"); return -EINVAL; } diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 537c70beaad0..ce926eb9feea 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1595,7 +1595,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) * file handles so user can use name_to_handle_at() to compare fids * reported with events to the file handle of watched objects. */ - if (!nop) + if (!exportfs_can_encode_fid(nop)) return -EOPNOTSUPP; /* @@ -1603,7 +1603,7 @@ static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) * supports decoding file handles, so user has a way to map back the * reported fids to filesystem objects. */ - if (mark_type != FAN_MARK_INODE && !nop->fh_to_dentry) + if (mark_type != FAN_MARK_INODE && !exportfs_can_decode_fh(nop)) return -EOPNOTSUPP; return 0; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 89e0d60d35b6..f0a712214ec2 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -55,7 +55,7 @@ int ovl_can_decode_fh(struct super_block *sb) if (!capable(CAP_DAC_READ_SEARCH)) return 0; - if (!sb->s_export_op || !sb->s_export_op->fh_to_dentry) + if (!exportfs_can_decode_fh(sb->s_export_op)) return 0; return sb->s_export_op->encode_fh ? -1 : FILEID_INO32_GEN; diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 11fbd0ee1370..5b3c9f30b422 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -233,6 +233,33 @@ extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len, int flags); +static inline bool exportfs_can_encode_fid(const struct export_operations *nop) +{ + return nop; +} + +static inline bool exportfs_can_decode_fh(const struct export_operations *nop) +{ + return nop && nop->fh_to_dentry; +} + +static inline bool exportfs_can_encode_fh(const struct export_operations *nop, + int fh_flags) +{ + /* + * If a non-decodeable file handle was requested, we only need to make + * sure that filesystem can encode file handles. + */ + if (fh_flags & EXPORT_FH_FID) + return exportfs_can_encode_fid(nop); + + /* + * If a decodeable file handle was requested, we need to make sure that + * filesystem can also decode file handles. + */ + return exportfs_can_decode_fh(nop); +} + static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid, int *max_len) {
The logic of whether filesystem can encode/decode file handles is open coded in many places. In preparation to changing the logic, move the open coded logic into inline helpers. Signed-off-by: Amir Goldstein <amir73il@gmail.com> --- fs/exportfs/expfs.c | 8 ++------ fs/fhandle.c | 6 +----- fs/nfsd/export.c | 3 +-- fs/notify/fanotify/fanotify_user.c | 4 ++-- fs/overlayfs/util.c | 2 +- include/linux/exportfs.h | 27 +++++++++++++++++++++++++++ 6 files changed, 34 insertions(+), 16 deletions(-)