mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Release SCL_STATE in map_write_done()
The config lock must be held for the duration of the MMP write. Since the I/Os are executed via map_nowait(), the done function is the only place where we know the write has completed. Since SCL_STATE is taken as reader, overlapping I/Os do not create a deadlock. The refcount is simply increased when new I/Os are queued and decreased when I/Os complete. Test case added which exercises the probe IO call path to verify the fix and prevent a regression. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Olaf Faaland <faaland1@llnl.gov> Closes #6394
This commit is contained in:
committed by
Brian Behlendorf
parent
f43615d0cc
commit
ffb195c256
+6
-5
@@ -287,6 +287,7 @@ mmp_write_done(zio_t *zio)
|
||||
|
||||
unlock:
|
||||
mutex_exit(&mts->mmp_io_lock);
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
|
||||
abd_free(zio->io_abd);
|
||||
}
|
||||
@@ -322,9 +323,12 @@ mmp_write_uberblock(spa_t *spa)
|
||||
int label;
|
||||
uint64_t offset;
|
||||
|
||||
spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
|
||||
vd = vdev_random_leaf(spa);
|
||||
if (vd == NULL || !vdev_writeable(vd))
|
||||
if (vd == NULL || !vdev_writeable(vd)) {
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_enter(&mmp->mmp_io_lock);
|
||||
|
||||
@@ -437,11 +441,8 @@ mmp_thread(spa_t *spa)
|
||||
zio_suspend(spa, NULL);
|
||||
}
|
||||
|
||||
if (multihost) {
|
||||
spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
|
||||
if (multihost)
|
||||
mmp_write_uberblock(spa);
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
}
|
||||
|
||||
CALLB_CPR_SAFE_BEGIN(&cpr);
|
||||
(void) cv_timedwait_sig(&mmp->mmp_thread_cv,
|
||||
|
||||
Reference in New Issue
Block a user