summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-10-19 18:10:23 -0400
committerBrian Behlendorf <[email protected]>2018-10-24 14:37:33 -0700
commit7ab96299e5b961c7d4c29344927f2c59e914545e (patch)
treef0ed8f4dfc1ed1f0ea480d49def74f5b69f16445 /module
parent4a7eb69a5ab0027a0f347a0cdd37b0275fcfecad (diff)
Fix ENXIO from spa_ld_verify_logs() in ztest
This patch fixes a small issue where the zil_check_log_chain() code path would hit an EBUSY error. This would occur when 2 threads attempted to call metaslab_activate() at the same time. In this case, the "loser" would receive an error code which should have been ignored, but was instead floated to the caller. This ended up resulting in an ENXIO being returned from from spa_ld_verify_logs(). Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Reviewed-by: Matthew Ahrens <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #8010
Diffstat (limited to 'module')
-rw-r--r--module/zfs/metaslab.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c
index a117dc446..616a89507 100644
--- a/module/zfs/metaslab.c
+++ b/module/zfs/metaslab.c
@@ -2049,7 +2049,7 @@ metaslab_activate(metaslab_t *msp, int allocator, uint64_t activation_weight)
* The metaslab was activated for another allocator
* while we were waiting, we should reselect.
*/
- return (EBUSY);
+ return (SET_ERROR(EBUSY));
}
if ((error = metaslab_activate_allocator(msp->ms_group, msp,
allocator, activation_weight)) != 0) {
@@ -3886,15 +3886,21 @@ metaslab_claim_concrete(vdev_t *vd, uint64_t offset, uint64_t size,
int error = 0;
if (offset >> vd->vdev_ms_shift >= vd->vdev_ms_count)
- return (ENXIO);
+ return (SET_ERROR(ENXIO));
ASSERT3P(vd->vdev_ms, !=, NULL);
msp = vd->vdev_ms[offset >> vd->vdev_ms_shift];
mutex_enter(&msp->ms_lock);
- if ((txg != 0 && spa_writeable(spa)) || !msp->ms_loaded)
+ if ((txg != 0 && spa_writeable(spa)) || !msp->ms_loaded) {
error = metaslab_activate(msp, 0, METASLAB_WEIGHT_CLAIM);
+ if (error == EBUSY) {
+ ASSERT(msp->ms_loaded);
+ ASSERT(msp->ms_weight & METASLAB_ACTIVE_MASK);
+ error = 0;
+ }
+ }
if (error == 0 &&
!range_tree_contains(msp->ms_allocatable, offset, size))