aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/spa_misc.c
diff options
context:
space:
mode:
authorPaul Dagnelie <[email protected]>2019-08-13 20:24:43 -0700
committerBrian Behlendorf <[email protected]>2019-08-13 21:24:43 -0600
commitdc04a8c757d7df91efbca05491174112540f6e7a (patch)
treea7f13ef90ddddd8c64e5af6f0ac9a4470ec4c27e /module/zfs/spa_misc.c
parent8e556c5ebc7b66caf2cdcc561b6644f9f8437a6d (diff)
Prevent race in blkptr_verify against device removal
When we check the vdev of the blkptr in zfs_blkptr_verify, we can run into a race condition where that vdev is temporarily unavailable. This happens when a device removal operation and the old vdev_t has been removed from the array, but the new indirect vdev has not yet been inserted. We hold the spa_config_lock while doing our sensitive verification. To ensure that we don't deadlock, we only grab the lock if we don't have config_writer held. In addition, I had to const the tags of the refcounts and the spa_config_lock arguments. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Signed-off-by: Paul Dagnelie <[email protected]> Closes #9112
Diffstat (limited to 'module/zfs/spa_misc.c')
-rw-r--r--module/zfs/spa_misc.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index 3d6c0ee3e..d998fe225 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -484,7 +484,7 @@ spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
}
void
-spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw)
+spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
{
int wlocks_held = 0;
@@ -517,7 +517,7 @@ spa_config_enter(spa_t *spa, int locks, void *tag, krw_t rw)
}
void
-spa_config_exit(spa_t *spa, int locks, void *tag)
+spa_config_exit(spa_t *spa, int locks, const void *tag)
{
for (int i = SCL_LOCKS - 1; i >= 0; i--) {
spa_config_lock_t *scl = &spa->spa_config_lock[i];