linux/zvol_os: fix zvol queue limits initialization

zvol queue limits initialization depends on `zv_volblocksize`, but it is
initialized later, leading to several limits being initialized with
incorrect values, including `max_discard_*` limits. This also causes
`blkdiscard` command to consistently fail, as `blk_ioctl_discard` reads
`bdev_max_discard_sectors()` limits as 0, leading to failure. The fix is
straightforward: initialize `zv->zv_volblocksize` early, before setting
the queue limits. This PR should fix `zvol/zvol_misc/zvol_misc_trim`
failure on recent PRs, as the test case issues `blkdiscard` for a zvol.
Additionally, `zvol_misc_trim` was recently enabled in `6c7d41a`,
which is why the issue wasn't identified earlier.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #16454
This commit is contained in:
Ameer Hamza 2024-08-16 02:29:50 +05:00 committed by Tony Hutter
parent d8fa32a79d
commit c60df6a801
1 changed files with 4 additions and 3 deletions

View File

@ -1343,7 +1343,7 @@ zvol_alloc_blk_mq(zvol_state_t *zv, zvol_queue_limits_t *limits)
* request queue and generic disk structures for the block device. * request queue and generic disk structures for the block device.
*/ */
static zvol_state_t * static zvol_state_t *
zvol_alloc(dev_t dev, const char *name) zvol_alloc(dev_t dev, const char *name, uint64_t volblocksize)
{ {
zvol_state_t *zv; zvol_state_t *zv;
struct zvol_state_os *zso; struct zvol_state_os *zso;
@ -1363,6 +1363,7 @@ zvol_alloc(dev_t dev, const char *name)
zso = kmem_zalloc(sizeof (struct zvol_state_os), KM_SLEEP); zso = kmem_zalloc(sizeof (struct zvol_state_os), KM_SLEEP);
zv->zv_zso = zso; zv->zv_zso = zso;
zv->zv_volmode = volmode; zv->zv_volmode = volmode;
zv->zv_volblocksize = volblocksize;
list_link_init(&zv->zv_next); list_link_init(&zv->zv_next);
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL);
@ -1649,7 +1650,8 @@ zvol_os_create_minor(const char *name)
if (error) if (error)
goto out_dmu_objset_disown; goto out_dmu_objset_disown;
zv = zvol_alloc(MKDEV(zvol_major, minor), name); zv = zvol_alloc(MKDEV(zvol_major, minor), name,
doi->doi_data_block_size);
if (zv == NULL) { if (zv == NULL) {
error = SET_ERROR(EAGAIN); error = SET_ERROR(EAGAIN);
goto out_dmu_objset_disown; goto out_dmu_objset_disown;
@ -1659,7 +1661,6 @@ zvol_os_create_minor(const char *name)
if (dmu_objset_is_snapshot(os)) if (dmu_objset_is_snapshot(os))
zv->zv_flags |= ZVOL_RDONLY; zv->zv_flags |= ZVOL_RDONLY;
zv->zv_volblocksize = doi->doi_data_block_size;
zv->zv_volsize = volsize; zv->zv_volsize = volsize;
zv->zv_objset = os; zv->zv_objset = os;