diff options
author | Matthew Ahrens <[email protected]> | 2020-07-29 17:04:34 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-29 17:04:34 -0700 |
commit | 3a92552f755543c02c71aa29d680261907b1bea3 (patch) | |
tree | 410926fec2dc776b335d73b09ab75d7a37514545 | |
parent | ae12b023082fd91e89507a2a1fc014e64c6767f0 (diff) |
Fix error handling of vdev_top_zap
In `vdev_load()`, we look up several entries in the `vdev_top_zap`
object. In most cases, if we encounter an i/o error, it will be
returned to the caller. However, when handling
`VDEV_TOP_ZAP_ALLOCATION_BIAS`, if we get an i/o error, we may continue
on, which in theory could cause us to not realize that a vdev should be
used only for `special` allocations.
In practice, if we encountered an i/o error while looking for
`VDEV_TOP_ZAP_ALLOCATION_BIAS` in the `vdev_top_zap`, we'd also get an
i/o error while looking for other entries in the same object, and thus
the zpool open/import would fail. Therefore the impact of this problem
is negligible.
This commit adds error handling for i/o errors while accessing the
`vdev_top_zap`, so that we aren't relying on unrelated code to fail for
us.
Reviewed-by: Don Brady <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Matthew Ahrens <[email protected]>
Closes #10637
-rw-r--r-- | module/zfs/vdev.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 27ac17fea..a51e427f8 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -3127,11 +3127,18 @@ vdev_load(vdev_t *vd) spa_t *spa = vd->vdev_spa; char bias_str[64]; - if (zap_lookup(spa->spa_meta_objset, vd->vdev_top_zap, + error = zap_lookup(spa->spa_meta_objset, vd->vdev_top_zap, VDEV_TOP_ZAP_ALLOCATION_BIAS, 1, sizeof (bias_str), - bias_str) == 0) { + bias_str); + if (error == 0) { ASSERT(vd->vdev_alloc_bias == VDEV_BIAS_NONE); vd->vdev_alloc_bias = vdev_derive_alloc_bias(bias_str); + } else if (error != ENOENT) { + vdev_set_state(vd, B_FALSE, VDEV_STATE_CANT_OPEN, + VDEV_AUX_CORRUPT_DATA); + vdev_dbgmsg(vd, "vdev_load: zap_lookup(top_zap=%llu) " + "failed [error=%d]", vd->vdev_top_zap, error); + return (error); } } @@ -3301,6 +3308,7 @@ vdev_destroy_ms_flush_data(vdev_t *vd, dmu_tx_t *tx) VDEV_TOP_ZAP_MS_UNFLUSHED_PHYS_TXGS, sizeof (uint64_t), 1, &object); if (err == ENOENT) return; + VERIFY0(err); VERIFY0(dmu_object_free(mos, object, tx)); VERIFY0(zap_remove(mos, vd->vdev_top_zap, |