Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux 6.9 compat for ZFS 2.1.x #16286

Draft
wants to merge 3 commits into
base: zfs-2.1.16-staging
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions config/kernel-blkdev.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
Expand All @@ -73,7 +94,15 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
[bdev_open_by_path() exists])
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()])
])
])
])
])
Expand Down Expand Up @@ -149,6 +178,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE], [
])
])

dnl #
dnl # 6.9.x API change
dnl # fput() replaces bdev_release()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_FPUT], [
ZFS_LINUX_TEST_SRC([fput], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct file *f = NULL;
fput(f);
])
])

AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_MSG_CHECKING([whether blkdev_put() exists])
ZFS_LINUX_TEST_RESULT([blkdev_put], [
Expand All @@ -168,7 +211,14 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_DEFINE(HAVE_BDEV_RELEASE, 1,
[bdev_release() exists])
], [
ZFS_LINUX_TEST_ERROR([blkdev_put()])
ZFS_LINUX_TEST_RESULT([fput], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BDEV_RELEASE_VIA_FPUT, 1,
[fput() can release a block device and exists]
)
], [
ZFS_LINUX_TEST_ERROR([blkdev_put()])
])
])
])
])
Expand Down Expand Up @@ -621,9 +671,11 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
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_HOLDER
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE
ZFS_AC_KERNEL_SRC_BLKDEV_FPUT
ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV
Expand Down
50 changes: 36 additions & 14 deletions config/kernel-make-request-fn.m4
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
disk = blk_alloc_disk(NUMA_NO_NODE);
])

ZFS_LINUX_TEST_SRC([blk_alloc_disk_2args], [
#include <linux/blkdev.h>
],[
struct gendisk *disk __attribute__ ((unused));
disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
])

ZFS_LINUX_TEST_SRC([blk_cleanup_disk], [
#include <linux/blkdev.h>
],[
Expand All @@ -71,30 +78,45 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1,
[submit_bio is member of struct block_device_operations])

dnl
dnl # Linux 6.9 API change
dnl # blk_alloc_disk() takes 2 arguments:
dnl # a queue limit and NUMA node ID.
dnl #
dnl # Linux 5.14 API Change:
dnl # blk_alloc_queue() + alloc_disk() combo replaced by
dnl # a single call to blk_alloc_disk().
dnl #
AC_MSG_CHECKING([whether blk_alloc_disk() exists])
ZFS_LINUX_TEST_RESULT([blk_alloc_disk], [
AC_MSG_CHECKING([whether blk_alloc_disk() takes 2 args])
ZFS_LINUX_TEST_RESULT([blk_alloc_disk_2args], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLK_ALLOC_DISK], 1, [blk_alloc_disk() exists])
AC_DEFINE([HAVE_BLK_ALLOC_DISK_2ARGS], 1, [blk_alloc_disk() takes 2 args])
dnl # put_disk() should be used in 6.9.
], [
AC_MSG_RESULT(no)

dnl #
dnl # 5.20 API change,
dnl # Removed blk_cleanup_disk(), put_disk() should be used.
dnl # Linux 5.14 API Change:
dnl # blk_alloc_queue() + alloc_disk() combo replaced by
dnl # a single call to blk_alloc_disk().
dnl #
AC_MSG_CHECKING([whether blk_cleanup_disk() exists])
ZFS_LINUX_TEST_RESULT([blk_cleanup_disk], [
AC_MSG_CHECKING([whether blk_alloc_disk() exists])
ZFS_LINUX_TEST_RESULT([blk_alloc_disk], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLK_CLEANUP_DISK], 1,
[blk_cleanup_disk() exists])
AC_DEFINE([HAVE_BLK_ALLOC_DISK], 1, [blk_alloc_disk() exists])

dnl #
dnl # 5.20 API change,
dnl # Removed blk_cleanup_disk(), put_disk() should be used.
dnl #
AC_MSG_CHECKING([whether blk_cleanup_disk() exists])
ZFS_LINUX_TEST_RESULT([blk_cleanup_disk], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_BLK_CLEANUP_DISK], 1,
[blk_cleanup_disk() exists])
], [
AC_MSG_RESULT(no)
])
], [
AC_MSG_RESULT(no)
])
], [
AC_MSG_RESULT(no)
])
],[
AC_MSG_RESULT(no)
Expand Down
16 changes: 15 additions & 1 deletion module/os/linux/zfs/vdev_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,26 @@
#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
* 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
* 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;
#define BDH_BDEV(bdh) ((bdh)->bdev)
#define BDH_IS_ERR(bdh) (IS_ERR(bdh))
#define BDH_PTR_ERR(bdh) (PTR_ERR(bdh))
#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))

Check failure on line 61 in module/os/linux/zfs/vdev_disk.c

View workflow job for this annotation

GitHub Actions / checkstyle

#define followed by space instead of tab
#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
typedef void zfs_bdev_handle_t;
#define BDH_BDEV(bdh) ((struct block_device *)bdh)
Expand Down Expand Up @@ -237,6 +246,9 @@
#if defined(HAVE_BDEV_OPEN_BY_PATH)
return (bdev_open_by_path(path,
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)
return (blkdev_get_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL));
Expand All @@ -251,6 +263,8 @@
{
#if defined(HAVE_BDEV_RELEASE)
return (bdev_release(bdh));
#elif defined(HAVE_BDEV_RELEASE_VIA_FPUT)
return (fput(bdh));
#elif defined(HAVE_BLKDEV_PUT_HOLDER)
return (blkdev_put(BDH_BDEV(bdh), holder));
#else
Expand Down
4 changes: 4 additions & 0 deletions module/os/linux/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,11 @@ zvol_alloc(dev_t dev, const char *name)

#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
#ifdef HAVE_BLK_ALLOC_DISK
#ifdef HAVE_BLK_ALLOC_DISK_2ARGS
zso->zvo_disk = blk_alloc_disk(NULL, NUMA_NO_NODE);
#else
zso->zvo_disk = blk_alloc_disk(NUMA_NO_NODE);
#endif
if (zso->zvo_disk == NULL)
goto out_kmem;

Expand Down
Loading