diff options
author | Paul Dagnelie <[email protected]> | 2019-08-13 20:24:43 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-08-13 21:24:43 -0600 |
commit | dc04a8c757d7df91efbca05491174112540f6e7a (patch) | |
tree | a7f13ef90ddddd8c64e5af6f0ac9a4470ec4c27e /module/zfs/spa_misc.c | |
parent | 8e556c5ebc7b66caf2cdcc561b6644f9f8437a6d (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.c | 4 |
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]; |