forked from openzfs/zfs
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
zvol: ensure device minors are properly cleaned up
Currently, if a minor is in use when we try to remove it, we'll skip it and never come back to it again. Since the zvol state is hung off the minor in the kernel, this can get us into weird situations if something tries to use it after the removal fails. It's even worse at pool export, as there's now a vestigial zvol state with no pool under it. It's weirder again if the pool is subsequently reimported, as the zvol code (reasonably) assumes the zvol state has been properly setup, when it's actually left over from the previous import of the pool. This commit attempts to tackle that by setting a flag on the zvol if its minor can't be removed, and then checking that flag when a request is made and rejecting it, thus stopping new work coming in. The flag also causes a condvar to be signaled when the last client finishes. For the case where a single minor is being removed (eg changing volmode), it will wait for this signal before proceeding. Meanwhile, when removing all minors, a background task is created for each minor that couldn't be removed on the spot, and those tasks then wake and clean up. Since any new tasks are queued on to the pool's spa_zvol_taskq, spa_export_common() will continue to wait at export until all minors are removed. Reviewed-by: Tony Hutter <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Rob Norris <[email protected]> Closes openzfs#14872 Closes openzfs#16364
- Loading branch information
1 parent
f3a9746
commit cf80a80
Showing
4 changed files
with
121 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ | |
* Copyright (c) 2012, 2017 by Delphix. All rights reserved. | ||
* Copyright (c) 2013, Joyent, Inc. All rights reserved. | ||
* Copyright (c) 2014 Integros [integros.com] | ||
* Copyright (c) 2024, Klara, Inc. | ||
*/ | ||
|
||
/* Portions Copyright 2011 Martin Matuska <[email protected]> */ | ||
|
@@ -251,7 +252,7 @@ zvol_geom_open(struct g_provider *pp, int flag, int count) | |
} | ||
|
||
mutex_enter(&zv->zv_state_lock); | ||
if (zv->zv_zso->zso_dying) { | ||
if (zv->zv_zso->zso_dying || zv->zv_flags & ZVOL_REMOVING) { | ||
rw_exit(&zvol_state_lock); | ||
err = SET_ERROR(ENXIO); | ||
goto out_zv_locked; | ||
|
@@ -683,6 +684,11 @@ zvol_geom_bio_strategy(struct bio *bp) | |
|
||
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER); | ||
|
||
if (zv->zv_flags & ZVOL_REMOVING) { | ||
error = SET_ERROR(ENXIO); | ||
goto resume; | ||
} | ||
|
||
switch (bp->bio_cmd) { | ||
case BIO_READ: | ||
doread = B_TRUE; | ||
|
@@ -1374,6 +1380,7 @@ zvol_os_free(zvol_state_t *zv) | |
} | ||
|
||
mutex_destroy(&zv->zv_state_lock); | ||
cv_destroy(&zv->zv_removing_cv); | ||
dataset_kstats_destroy(&zv->zv_kstat); | ||
kmem_free(zv->zv_zso, sizeof (struct zvol_state_os)); | ||
kmem_free(zv, sizeof (zvol_state_t)); | ||
|
@@ -1431,6 +1438,7 @@ zvol_os_create_minor(const char *name) | |
zv = kmem_zalloc(sizeof (*zv), KM_SLEEP); | ||
zv->zv_hash = hash; | ||
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL); | ||
cv_init(&zv->zv_removing_cv, NULL, CV_DEFAULT, NULL); | ||
zv->zv_zso = kmem_zalloc(sizeof (struct zvol_state_os), KM_SLEEP); | ||
zv->zv_volmode = volmode; | ||
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
/* | ||
* Copyright (c) 2012, 2020 by Delphix. All rights reserved. | ||
* Copyright (c) 2024, Rob Norris <[email protected]> | ||
* Copyright (c) 2024, Klara, Inc. | ||
*/ | ||
|
||
#include <sys/dataset_kstats.h> | ||
|
@@ -527,6 +528,11 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq, | |
uint64_t size = io_size(bio, rq); | ||
int rw = io_data_dir(bio, rq); | ||
|
||
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) { | ||
END_IO(zv, bio, rq, -SET_ERROR(ENXIO)); | ||
goto out; | ||
} | ||
|
||
if (zvol_request_sync) | ||
force_sync = 1; | ||
|
||
|
@@ -735,6 +741,13 @@ zvol_open(struct block_device *bdev, fmode_t flag) | |
} | ||
|
||
mutex_enter(&zv->zv_state_lock); | ||
|
||
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) { | ||
mutex_exit(&zv->zv_state_lock); | ||
rw_exit(&zvol_state_lock); | ||
return (-SET_ERROR(ENXIO)); | ||
} | ||
|
||
/* | ||
* Make sure zvol is not suspended during first open | ||
* (hold zv_suspend_lock) and respect proper lock acquisition | ||
|
@@ -1368,6 +1381,7 @@ zvol_alloc(dev_t dev, const char *name, uint64_t volblocksize) | |
|
||
list_link_init(&zv->zv_next); | ||
mutex_init(&zv->zv_state_lock, NULL, MUTEX_DEFAULT, NULL); | ||
cv_init(&zv->zv_removing_cv, NULL, CV_DEFAULT, NULL); | ||
|
||
#ifdef HAVE_BLK_MQ | ||
zv->zv_zso->use_blk_mq = zvol_use_blk_mq; | ||
|
@@ -1488,6 +1502,7 @@ zvol_os_free(zvol_state_t *zv) | |
ida_simple_remove(&zvol_ida, | ||
MINOR(zv->zv_zso->zvo_dev) >> ZVOL_MINOR_BITS); | ||
|
||
cv_destroy(&zv->zv_removing_cv); | ||
mutex_destroy(&zv->zv_state_lock); | ||
dataset_kstats_destroy(&zv->zv_kstat); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters