Linux 5.10 compat: check_disk_change() removed
Kernel 5.10 removed check_disk_change() in favor of callers using the faster bdev_check_media_change() instead, and explicitly forcing bdev revalidation when they desire that behavior. To preserve prior behavior, I have wrapped this into a zfs_check_media_change() macro that calls an inline function for the new API that mimics the old behavior when check_disk_change() doesn't exist, and just calls check_disk_change() if it exists. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Coleman Kane <ckane@colemankane.org> Closes #11085
This commit is contained in:
parent
838a249012
commit
ae15f1c1d8
|
@ -77,6 +77,59 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # check_disk_change() was removed in 5.10
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE], [
|
||||
ZFS_LINUX_TEST_SRC([check_disk_change], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
bool error;
|
||||
|
||||
error = check_disk_change(bdev);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE], [
|
||||
AC_MSG_CHECKING([whether check_disk_change() exists])
|
||||
ZFS_LINUX_TEST_RESULT([check_disk_change], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_CHECK_DISK_CHANGE, 1,
|
||||
[check_disk_change() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.10 API, check_disk_change() is removed, in favor of
|
||||
dnl # bdev_check_media_change(), which doesn't force revalidation
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_check_media_change], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
int error;
|
||||
|
||||
error = bdev_check_media_change(bdev);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE], [
|
||||
AC_MSG_CHECKING([whether bdev_disk_changed() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_check_media_change], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_CHECK_MEDIA_CHANGE, 1,
|
||||
[bdev_check_media_change() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.22 API change
|
||||
dnl # Single argument invalidate_bdev()
|
||||
|
@ -199,6 +252,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
|||
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_CHECK_DISK_CHANGE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||
|
@ -209,4 +264,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
|||
ZFS_AC_KERNEL_BLKDEV_LOOKUP_BDEV
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE
|
||||
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
|
||||
])
|
||||
|
|
|
@ -268,12 +268,48 @@ bio_set_bi_error(struct bio *bio, int error)
|
|||
*
|
||||
* For older kernels trigger a re-reading of the partition table by calling
|
||||
* check_disk_change() which calls flush_disk() to invalidate the device.
|
||||
*
|
||||
* For newer kernels (as of 5.10), bdev_check_media_chage is used, in favor of
|
||||
* check_disk_change(), with the modification that invalidation is no longer
|
||||
* forced.
|
||||
*/
|
||||
#ifdef HAVE_CHECK_DISK_CHANGE
|
||||
#define zfs_check_media_change(bdev) check_disk_change(bdev)
|
||||
#ifdef HAVE_BLKDEV_REREAD_PART
|
||||
#define vdev_bdev_reread_part(bdev) blkdev_reread_part(bdev)
|
||||
#else
|
||||
#define vdev_bdev_reread_part(bdev) check_disk_change(bdev)
|
||||
#endif /* HAVE_BLKDEV_REREAD_PART */
|
||||
#else
|
||||
#ifdef HAVE_BDEV_CHECK_MEDIA_CHANGE
|
||||
static inline int
|
||||
zfs_check_media_change(struct block_device *bdev)
|
||||
{
|
||||
struct gendisk *gd = bdev->bd_disk;
|
||||
const struct block_device_operations *bdo = gd->fops;
|
||||
|
||||
if (!bdev_check_media_change(bdev))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Force revalidation, to mimic the old behavior of
|
||||
* check_disk_change()
|
||||
*/
|
||||
if (bdo->revalidate_disk)
|
||||
bdo->revalidate_disk(gd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#define vdev_bdev_reread_part(bdev) zfs_check_media_change(bdev)
|
||||
#else
|
||||
/*
|
||||
* This is encountered if check_disk_change() and bdev_check_media_change()
|
||||
* are not available in the kernel - likely due to an API change that needs
|
||||
* to be chased down.
|
||||
*/
|
||||
#error "Unsupported kernel: no usable disk change check"
|
||||
#endif /* HAVE_BDEV_CHECK_MEDIA_CHANGE */
|
||||
#endif /* HAVE_CHECK_DISK_CHANGE */
|
||||
|
||||
/*
|
||||
* 2.6.27 API change
|
||||
|
|
|
@ -791,7 +791,7 @@ vdev_disk_io_done(zio_t *zio)
|
|||
vdev_t *v = zio->io_vd;
|
||||
vdev_disk_t *vd = v->vdev_tsd;
|
||||
|
||||
if (check_disk_change(vd->vd_bdev)) {
|
||||
if (zfs_check_media_change(vd->vd_bdev)) {
|
||||
invalidate_bdev(vd->vd_bdev);
|
||||
v->vdev_remove_wanted = B_TRUE;
|
||||
spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE);
|
||||
|
|
|
@ -503,7 +503,7 @@ zvol_open(struct block_device *bdev, fmode_t flag)
|
|||
if (drop_suspend)
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
|
||||
check_disk_change(bdev);
|
||||
zfs_check_media_change(bdev);
|
||||
|
||||
return (0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue