Linux 6.9 compat: bdev_open_by_path

Support the new `bdev_open_by_path` API introduced in
https://lore.kernel.org/all/20240123-vfs-bdev-file-v2-0-adbd023e19cc@kernel.org/.

Signed-off-by: Ryan Lahfa <ryan@lahfa.xyz>
This commit is contained in:
Ryan Lahfa 2024-06-21 00:16:35 +02:00
parent 5b81b1bf5e
commit b1f9a75abb
2 changed files with 44 additions and 2 deletions

View File

@ -54,6 +54,27 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH], [
]) ])
]) ])
dnl #
dnl # 6.9.x API change
dnl # bdev_file_open_by_path() replaces bdev_open_by_path()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH], [
ZFS_LINUX_TEST_SRC([bdev_file_open_by_path], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct file *bdev_file __attribute__ ((unused)) = NULL;
const char *path = "path";
fmode_t mode = 0;
void *holder = NULL;
struct blk_holder_ops h;
bdev_file = bdev_file_open_by_path(path, mode, holder, &h);
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args]) AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
@ -73,7 +94,15 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
[bdev_open_by_path() exists]) [bdev_open_by_path() exists])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
], [ ], [
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether bdev_file_open_by_path() exists])
ZFS_LINUX_TEST_RESULT([bdev_file_open_by_path], [
AC_DEFINE(HAVE_BDEV_FILE_OPEN_BY_PATH, 1,
[bdev_file_open_by_path() exists])
AC_MSG_RESULT(yes)
], [
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path() or bdev_open_by_path() or bdev_file_open_by_path()])
])
]) ])
]) ])
]) ])
@ -621,6 +650,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_PUT ZFS_AC_KERNEL_SRC_BLKDEV_PUT
ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE

View File

@ -42,17 +42,26 @@
#endif #endif
/* /*
* Linux 6.9.x uses a file as an instance/refcount for an underlying
* block_device. We follow the same methodology as in Linux 6.8.x for it.
*
* Linux 6.8.x uses a bdev_handle as an instance/refcount for an underlying * Linux 6.8.x uses a bdev_handle as an instance/refcount for an underlying
* block_device. Since it carries the block_device inside, its convenient to * block_device. Since it carries the block_device inside, its convenient to
* just use the handle as a proxy. For pre-6.8, we just emulate this with * just use the handle as a proxy. For pre-6.8, we just emulate this with
* a cast, since we don't need any of the other fields inside the handle. * a cast, since we don't need any of the other fields inside the handle.
*/ */
#ifdef HAVE_BDEV_OPEN_BY_PATH #if defined(HAVE_BDEV_OPEN_BY_PATH)
typedef struct bdev_handle zfs_bdev_handle_t; typedef struct bdev_handle zfs_bdev_handle_t;
#define BDH_BDEV(bdh) ((bdh)->bdev) #define BDH_BDEV(bdh) ((bdh)->bdev)
#define BDH_IS_ERR(bdh) (IS_ERR(bdh)) #define BDH_IS_ERR(bdh) (IS_ERR(bdh))
#define BDH_PTR_ERR(bdh) (PTR_ERR(bdh)) #define BDH_PTR_ERR(bdh) (PTR_ERR(bdh))
#define BDH_ERR_PTR(err) (ERR_PTR(err)) #define BDH_ERR_PTR(err) (ERR_PTR(err))
#elif defined(HAVE_BDEV_FILE_OPEN_BY_PATH)
typedef struct file zfs_bdev_handle_t;
#define BDH_BDEV(bdh) (file_bdev(bdh))
#define BDH_IS_ERR(bdh) (IS_ERR(bdh))
#define BDH_PTR_ERR(bdh) (PTR_ERR(bdh))
#define BDH_ERR_PTR(err) (ERR_PTR(err))
#else #else
typedef void zfs_bdev_handle_t; typedef void zfs_bdev_handle_t;
#define BDH_BDEV(bdh) ((struct block_device *)bdh) #define BDH_BDEV(bdh) ((struct block_device *)bdh)
@ -237,6 +246,9 @@ vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder)
#if defined(HAVE_BDEV_OPEN_BY_PATH) #if defined(HAVE_BDEV_OPEN_BY_PATH)
return (bdev_open_by_path(path, return (bdev_open_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL)); vdev_bdev_mode(mode, B_TRUE), holder, NULL));
#elif defined(HAVE_BDEV_FILE_OPEN_BY_PATH)
return (bdev_file_open_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL));
#elif defined(HAVE_BLKDEV_GET_BY_PATH_4ARG) #elif defined(HAVE_BLKDEV_GET_BY_PATH_4ARG)
return (blkdev_get_by_path(path, return (blkdev_get_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL)); vdev_bdev_mode(mode, B_TRUE), holder, NULL));