diff mbox series

[2/5] exportfs: add helpers to check if filesystem can encode/decode file handles

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

Commit Message

Amir Goldstein Oct. 18, 2023, 9:59 a.m. UTC
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(-)

Comments

Jeffrey Layton Oct. 18, 2023, 2:15 p.m. UTC | #1
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>
Jan Kara Oct. 19, 2023, 2:23 p.m. UTC | #2
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 mbox series

Patch

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)
 {