summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2014-02-17 18:25:41 +0000
committeravg <avg@FreeBSD.org>2014-02-17 18:25:41 +0000
commit489e9199469312bfa8a4485ea401738f13296942 (patch)
tree023e997449769dd55a53ddb51d21497877551fda /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
parentb0a412937022eafe8c2d5bbc56abe56fd7b1b098 (diff)
downloadFreeBSD-src-489e9199469312bfa8a4485ea401738f13296942.zip
FreeBSD-src-489e9199469312bfa8a4485ea401738f13296942.tar.gz
MFC r260185: MFV r260155: 4391 panic system rather than corrupting pool if we hit bug 4390
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
index a0c90cc..41b166c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c
@@ -180,6 +180,7 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
err = 0;
for (i = ba.ba_phys->bt_begin; i < ba.ba_phys->bt_end; i++) {
bptree_entry_phys_t bte;
+ int flags = TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST;
ASSERT(!free || i == ba.ba_phys->bt_begin);
@@ -188,13 +189,13 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
if (err != 0)
break;
+ if (zfs_recover)
+ flags |= TRAVERSE_HARD;
err = traverse_dataset_destroyed(os->os_spa, &bte.be_bp,
- bte.be_birth_txg, &bte.be_zb,
- TRAVERSE_PREFETCH_METADATA | TRAVERSE_POST,
+ bte.be_birth_txg, &bte.be_zb, flags,
bptree_visit_cb, &ba);
if (free) {
- ASSERT(err == 0 || err == ERESTART);
- if (err != 0) {
+ if (err == ERESTART) {
/* save bookmark for future resume */
ASSERT3U(bte.be_zb.zb_objset, ==,
ZB_DESTROYED_OBJSET);
@@ -202,11 +203,21 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func,
dmu_write(os, obj, i * sizeof (bte),
sizeof (bte), &bte, tx);
break;
- } else {
- ba.ba_phys->bt_begin++;
- (void) dmu_free_range(os, obj,
- i * sizeof (bte), sizeof (bte), tx);
}
+ if (err != 0) {
+ /*
+ * We can not properly handle an i/o
+ * error, because the traversal code
+ * does not know how to resume from an
+ * arbitrary bookmark.
+ */
+ zfs_panic_recover("error %u from "
+ "traverse_dataset_destroyed()", err);
+ }
+
+ ba.ba_phys->bt_begin++;
+ (void) dmu_free_range(os, obj,
+ i * sizeof (bte), sizeof (bte), tx);
}
}
OpenPOWER on IntegriCloud