Linux 5.14 compat: blk_alloc_disk()

In Linux 5.14, blk_alloc_queue is no longer exported, and its usage
has been superseded by blk_alloc_disk, which returns a gendisk struct
from which we can still retrieve the struct request_queue* that is
needed in the one place where it is used. This also replaces the call
to alloc_disk(minors), and minors is now set via struct member
assignment.

Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com>
Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Reviewed-by: Coleman Kane <ckane@colemankane.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #12362
Closes #12409
This commit is contained in:
Brian Behlendorf 2021-07-23 15:28:03 -07:00 committed by Tony Hutter
parent 0c4f86be74
commit 36d50b60d8
2 changed files with 56 additions and 11 deletions

View File

@ -42,6 +42,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [
struct block_device_operations o; struct block_device_operations o;
o.submit_bio = NULL; o.submit_bio = NULL;
]) ])
ZFS_LINUX_TEST_SRC([blk_alloc_disk], [
#include <linux/blkdev.h>
],[
struct gendisk *disk __attribute__ ((unused));
disk = blk_alloc_disk(NUMA_NO_NODE);
])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
@ -56,6 +63,19 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1, AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1,
[submit_bio is member of struct block_device_operations]) [submit_bio is member of struct block_device_operations])
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_RESULT(yes)
AC_DEFINE([HAVE_BLK_ALLOC_DISK], 1, [blk_alloc_disk() exists])
], [
AC_MSG_RESULT(no)
])
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)

View File

@ -760,13 +760,40 @@ zvol_alloc(dev_t dev, const char *name)
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL);
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS #ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
zso->zvo_queue = blk_alloc_queue(NUMA_NO_NODE); #ifdef HAVE_BLK_ALLOC_DISK
zso->zvo_disk = blk_alloc_disk(NUMA_NO_NODE);
if (zso->zvo_disk == NULL)
goto out_kmem;
zso->zvo_disk->minors = ZVOL_MINORS;
zso->zvo_queue = zso->zvo_disk->queue;
#else #else
zso->zvo_queue = blk_generic_alloc_queue(zvol_request, NUMA_NO_NODE); zso->zvo_queue = blk_alloc_queue(NUMA_NO_NODE);
#endif
if (zso->zvo_queue == NULL) if (zso->zvo_queue == NULL)
goto out_kmem; goto out_kmem;
zso->zvo_disk = alloc_disk(ZVOL_MINORS);
if (zso->zvo_disk == NULL) {
blk_cleanup_queue(zso->zvo_queue);
goto out_kmem;
}
zso->zvo_disk->queue = zso->zvo_queue;
#endif /* HAVE_BLK_ALLOC_DISK */
#else
zso->zvo_queue = blk_generic_alloc_queue(zvol_request, NUMA_NO_NODE);
if (zso->zvo_queue == NULL)
goto out_kmem;
zso->zvo_disk = alloc_disk(ZVOL_MINORS);
if (zso->zvo_disk == NULL) {
blk_cleanup_queue(zso->zvo_queue);
goto out_kmem;
}
zso->zvo_disk->queue = zso->zvo_queue;
#endif /* HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS */
blk_queue_set_write_cache(zso->zvo_queue, B_TRUE, B_TRUE); blk_queue_set_write_cache(zso->zvo_queue, B_TRUE, B_TRUE);
/* Limit read-ahead to a single page to prevent over-prefetching. */ /* Limit read-ahead to a single page to prevent over-prefetching. */
@ -775,10 +802,6 @@ zvol_alloc(dev_t dev, const char *name)
/* Disable write merging in favor of the ZIO pipeline. */ /* Disable write merging in favor of the ZIO pipeline. */
blk_queue_flag_set(QUEUE_FLAG_NOMERGES, zso->zvo_queue); blk_queue_flag_set(QUEUE_FLAG_NOMERGES, zso->zvo_queue);
zso->zvo_disk = alloc_disk(ZVOL_MINORS);
if (zso->zvo_disk == NULL)
goto out_queue;
zso->zvo_queue->queuedata = zv; zso->zvo_queue->queuedata = zv;
zso->zvo_dev = dev; zso->zvo_dev = dev;
zv->zv_open_count = 0; zv->zv_open_count = 0;
@ -809,14 +832,11 @@ zvol_alloc(dev_t dev, const char *name)
zso->zvo_disk->first_minor = (dev & MINORMASK); zso->zvo_disk->first_minor = (dev & MINORMASK);
zso->zvo_disk->fops = &zvol_ops; zso->zvo_disk->fops = &zvol_ops;
zso->zvo_disk->private_data = zv; zso->zvo_disk->private_data = zv;
zso->zvo_disk->queue = zso->zvo_queue;
snprintf(zso->zvo_disk->disk_name, DISK_NAME_LEN, "%s%d", snprintf(zso->zvo_disk->disk_name, DISK_NAME_LEN, "%s%d",
ZVOL_DEV_NAME, (dev & MINORMASK)); ZVOL_DEV_NAME, (dev & MINORMASK));
return (zv); return (zv);
out_queue:
blk_cleanup_queue(zso->zvo_queue);
out_kmem: out_kmem:
kmem_free(zso, sizeof (struct zvol_state_os)); kmem_free(zso, sizeof (struct zvol_state_os));
kmem_free(zv, sizeof (zvol_state_t)); kmem_free(zv, sizeof (zvol_state_t));
@ -847,8 +867,13 @@ zvol_free(zvol_state_t *zv)
zfs_rangelock_fini(&zv->zv_rangelock); zfs_rangelock_fini(&zv->zv_rangelock);
del_gendisk(zv->zv_zso->zvo_disk); del_gendisk(zv->zv_zso->zvo_disk);
#if defined(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS) && \
defined(HAVE_BLK_ALLOC_DISK)
blk_cleanup_disk(zv->zv_zso->zvo_disk);
#else
blk_cleanup_queue(zv->zv_zso->zvo_queue); blk_cleanup_queue(zv->zv_zso->zvo_queue);
put_disk(zv->zv_zso->zvo_disk); put_disk(zv->zv_zso->zvo_disk);
#endif
ida_simple_remove(&zvol_ida, ida_simple_remove(&zvol_ida,
MINOR(zv->zv_zso->zvo_dev) >> ZVOL_MINOR_BITS); MINOR(zv->zv_zso->zvo_dev) >> ZVOL_MINOR_BITS);