]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
exportfs: add helpers to check if filesystem can encode/decode file handles
authorAmir Goldstein <amir73il@gmail.com>
Mon, 23 Oct 2023 18:07:58 +0000 (21:07 +0300)
committerChristian Brauner <brauner@kernel.org>
Tue, 24 Oct 2023 15:57:45 +0000 (17:57 +0200)
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.

Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://lore.kernel.org/r/20231023180801.2953446-2-amir73il@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/exportfs/expfs.c
fs/fhandle.c
fs/nfsd/export.c
fs/notify/fanotify/fanotify_user.c
fs/overlayfs/util.c
include/linux/exportfs.h

index c20704aa21b3d0d058dbcc915c59d66b4e337497..9ee205df8fa76fe02be2c33f1fbc16e9e69fcb8e 100644 (file)
@@ -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))
index 6ea8d35a9382ace3fac22b89c818c74f0f123c34..18b3ba8dc8ead7c6016a1f76d96275268b0667f0 100644 (file)
@@ -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)))
index 11a0eaa2f9140728298ba4d011fd05984c884bcd..dc99dfc1d41157b84e28a58f784aa806228bb6f1 100644 (file)
@@ -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;
        }
index 62fe0b679e586ccbe181000fe94ed5e2b142b203..0eb9622e8a9f66067d33892d28f2e9b8fb0fc011 100644 (file)
@@ -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;
index 89e0d60d35b6cf6f07cba9a367513b66d41bb32d..f0a712214ec22762b447c72fffb0ff4d076faf5d 100644 (file)
@@ -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;
index 11fbd0ee1370809f9f1770aba8e8e3d3cec27be5..5b3c9f30b422ada43ec1b1d6e8eedfbc82da1d48 100644 (file)
@@ -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)
 {