]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Linux 5.11 compat: lookup_bdev()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 22 Dec 2020 18:26:45 +0000 (10:26 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 5 Jan 2021 18:26:09 +0000 (10:26 -0800)
The lookup_bdev() function has been updated to require a dev_t
be passed as the second argument. This is actually pretty nice
since the major number stored in the dev_t was the only part we
were interested in. This allows to us avoid handling the bdev
entirely.  The vdev_lookup_bdev() wrapper was updated to emulate
the behavior of the new lookup_bdev() for all supported kernels.

Reviewed-by: Rafael Kitover <rkitover@gmail.com>
Reviewed-by: Coleman Kane <ckane@colemankane.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #11387
Closes #11390

config/kernel-blkdev.m4
include/os/linux/kernel/linux/blkdev_compat.h
module/os/linux/zfs/zvol_os.c

index 530b49f48c8d2506a5cf5b24ae4ba223946d1840..622a1af5d0e067d18f70df6b670cef8fe64b98ea 100644 (file)
@@ -154,42 +154,69 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_INVALIDATE_BDEV], [
 ])
 
 dnl #
-dnl # 2.6.27, lookup_bdev() was exported.
-dnl # 4.4.0-6.21 - lookup_bdev() takes 2 arguments.
+dnl # 5.11 API, lookup_bdev() takes dev_t argument.
+dnl # 2.6.27 API, lookup_bdev() was first exported.
+dnl # 4.4.0-6.21 API, lookup_bdev() on Ubuntu takes mode argument.
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV], [
+       ZFS_LINUX_TEST_SRC([lookup_bdev_devt], [
+               #include <linux/blkdev.h>
+       ], [
+               int error __attribute__ ((unused));
+               const char path[] = "/example/path";
+               dev_t dev;
+
+               error = lookup_bdev(path, &dev);
+       ])
+
        ZFS_LINUX_TEST_SRC([lookup_bdev_1arg], [
                #include <linux/fs.h>
                #include <linux/blkdev.h>
        ], [
-               lookup_bdev(NULL);
+               struct block_device *bdev __attribute__ ((unused));
+               const char path[] = "/example/path";
+
+               bdev = lookup_bdev(path);
        ])
 
-       ZFS_LINUX_TEST_SRC([lookup_bdev_2args], [
+       ZFS_LINUX_TEST_SRC([lookup_bdev_mode], [
                #include <linux/fs.h>
        ], [
-               lookup_bdev(NULL, FMODE_READ);
+               struct block_device *bdev __attribute__ ((unused));
+               const char path[] = "/example/path";
+
+               bdev = lookup_bdev(path, FMODE_READ);
        ])
 ])
 
 AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_LOOKUP_BDEV], [
-       AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
-       ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_1arg],
+       AC_MSG_CHECKING([whether lookup_bdev() wants dev_t arg])
+       ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_devt],
            [lookup_bdev], [fs/block_dev.c], [
                AC_MSG_RESULT(yes)
-               AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1,
-                   [lookup_bdev() wants 1 arg])
+               AC_DEFINE(HAVE_DEVT_LOOKUP_BDEV, 1,
+                   [lookup_bdev() wants dev_t arg])
        ], [
                AC_MSG_RESULT(no)
 
-               AC_MSG_CHECKING([whether lookup_bdev() wants 2 args])
-               ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_2args],
+               AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
+               ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_1arg],
                    [lookup_bdev], [fs/block_dev.c], [
                        AC_MSG_RESULT(yes)
-                       AC_DEFINE(HAVE_2ARGS_LOOKUP_BDEV, 1,
-                           [lookup_bdev() wants 2 args])
+                       AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1,
+                           [lookup_bdev() wants 1 arg])
                ], [
-                       ZFS_LINUX_TEST_ERROR([lookup_bdev()])
+                       AC_MSG_RESULT(no)
+
+                       AC_MSG_CHECKING([whether lookup_bdev() wants mode arg])
+                       ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_mode],
+                           [lookup_bdev], [fs/block_dev.c], [
+                               AC_MSG_RESULT(yes)
+                               AC_DEFINE(HAVE_MODE_LOOKUP_BDEV, 1,
+                                   [lookup_bdev() wants mode arg])
+                       ], [
+                               ZFS_LINUX_TEST_ERROR([lookup_bdev()])
+                       ])
                ])
        ])
 ])
index 220344c814f982d58679ff2f3cdb07a8265ad589..4d84900becac79dc51afbf4790d7e6146d85b322 100644 (file)
@@ -318,16 +318,38 @@ zfs_check_media_change(struct block_device *bdev)
  *
  * 4.4.0-6.21 API change for Ubuntu
  * lookup_bdev() gained a second argument, FMODE_*, to check inode permissions.
+ *
+ * 5.11 API change
+ * Changed to take a dev_t argument which is set on success and return a
+ * non-zero error code on failure.
  */
-#ifdef HAVE_1ARG_LOOKUP_BDEV
-#define        vdev_lookup_bdev(path)  lookup_bdev(path)
-#else
-#ifdef HAVE_2ARGS_LOOKUP_BDEV
-#define        vdev_lookup_bdev(path)  lookup_bdev(path, 0)
+static inline int
+vdev_lookup_bdev(const char *path, dev_t *dev)
+{
+#if defined(HAVE_DEVT_LOOKUP_BDEV)
+       return (lookup_bdev(path, dev));
+#elif defined(HAVE_1ARG_LOOKUP_BDEV)
+       struct block_device *bdev = lookup_bdev(path);
+       if (IS_ERR(bdev))
+               return (PTR_ERR(bdev));
+
+       *dev = bdev->bd_dev;
+       bdput(bdev);
+
+       return (0);
+#elif defined(HAVE_MODE_LOOKUP_BDEV)
+       struct block_device *bdev = lookup_bdev(path, FMODE_READ);
+       if (IS_ERR(bdev))
+               return (PTR_ERR(bdev));
+
+       *dev = bdev->bd_dev;
+       bdput(bdev);
+
+       return (0);
 #else
 #error "Unsupported kernel"
-#endif /* HAVE_2ARGS_LOOKUP_BDEV */
-#endif /* HAVE_1ARG_LOOKUP_BDEV */
+#endif
+}
 
 /*
  * Kernels without bio_set_op_attrs use bi_rw for the bio flags.
index 3b1d3e4f80dc62205e77d211fa6b48a681d23883..29ad67368423330f85a47f6b39d68f6c89799ff9 100644 (file)
@@ -66,19 +66,14 @@ typedef struct zv_request {
  * Given a path, return TRUE if path is a ZVOL.
  */
 static boolean_t
-zvol_is_zvol_impl(const char *device)
+zvol_is_zvol_impl(const char *path)
 {
-       struct block_device *bdev;
-       unsigned int major;
+       dev_t dev = 0;
 
-       bdev = vdev_lookup_bdev(device);
-       if (IS_ERR(bdev))
+       if (vdev_lookup_bdev(path, &dev) != 0)
                return (B_FALSE);
 
-       major = MAJOR(bdev->bd_dev);
-       bdput(bdev);
-
-       if (major == zvol_major)
+       if (MAJOR(dev) == zvol_major)
                return (B_TRUE);
 
        return (B_FALSE);