75b07eca3e
by importing the upstream release as patches. replace user namespace patch with version which has been applied usptream.
117 lines
3.7 KiB
Diff
117 lines
3.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Chunwei Chen <david.chen@nutanix.com>
|
|
Date: Tue, 30 Jan 2018 13:39:11 -0800
|
|
Subject: [PATCH] Fix zdb -c traverse stop on damaged objset root
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
If a corruption happens to be on a root block of an objset, zdb -c will
|
|
not correctly report the error, and it will not traverse the datasets
|
|
that come after. This is because traverse_visitbp, which does the
|
|
callback and reset error for TRAVERSE_HARD, is skipped when traversing
|
|
zil is failed in traverse_impl.
|
|
|
|
Here's example of what 'zdb -eLcc' command looks like on a pool with
|
|
damaged objset root:
|
|
|
|
== before patch:
|
|
|
|
Traversing all blocks to verify checksums ...
|
|
|
|
Error counts:
|
|
|
|
errno count
|
|
block traversal size 379392 != alloc 33987072 (unreachable 33607680)
|
|
|
|
bp count: 172
|
|
ganged count: 0
|
|
bp logical: 1678336 avg: 9757
|
|
bp physical: 130560 avg: 759 compression: 12.85
|
|
bp allocated: 379392 avg: 2205 compression: 4.42
|
|
bp deduped: 0 ref>1: 0 deduplication: 1.00
|
|
SPA allocated: 33987072 used: 0.80%
|
|
|
|
additional, non-pointer bps of type 0: 71
|
|
Dittoed blocks on same vdev: 101
|
|
|
|
== after patch:
|
|
|
|
Traversing all blocks to verify checksums ...
|
|
|
|
zdb_blkptr_cb: Got error 52 reading <54, 0, -1, 0> -- skipping
|
|
|
|
Error counts:
|
|
|
|
errno count
|
|
52 1
|
|
block traversal size 33963520 != alloc 33987072 (unreachable 23552)
|
|
|
|
bp count: 447
|
|
ganged count: 0
|
|
bp logical: 36093440 avg: 80745
|
|
bp physical: 33699840 avg: 75391 compression: 1.07
|
|
bp allocated: 33963520 avg: 75981 compression: 1.06
|
|
bp deduped: 0 ref>1: 0 deduplication: 1.00
|
|
SPA allocated: 33987072 used: 0.80%
|
|
|
|
additional, non-pointer bps of type 0: 76
|
|
Dittoed blocks on same vdev: 115
|
|
|
|
==
|
|
|
|
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
|
|
Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
|
|
Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
|
|
Closes #7099
|
|
(cherry picked from commit 23227313a2016449176cbfcbae2d4fc463a2bc09)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
module/zfs/dmu_traverse.c | 26 +++++++++++++++++---------
|
|
1 file changed, 17 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c
|
|
index c78228d74..b494bef35 100644
|
|
--- a/module/zfs/dmu_traverse.c
|
|
+++ b/module/zfs/dmu_traverse.c
|
|
@@ -599,19 +599,27 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
|
|
|
|
/* See comment on ZIL traversal in dsl_scan_visitds. */
|
|
if (ds != NULL && !ds->ds_is_snapshot && !BP_IS_HOLE(rootbp)) {
|
|
+ enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
|
|
uint32_t flags = ARC_FLAG_WAIT;
|
|
objset_phys_t *osp;
|
|
arc_buf_t *buf;
|
|
|
|
- err = arc_read(NULL, td->td_spa, rootbp,
|
|
- arc_getbuf_func, &buf,
|
|
- ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, czb);
|
|
- if (err != 0)
|
|
- return (err);
|
|
-
|
|
- osp = buf->b_data;
|
|
- traverse_zil(td, &osp->os_zil_header);
|
|
- arc_buf_destroy(buf, &buf);
|
|
+ err = arc_read(NULL, td->td_spa, rootbp, arc_getbuf_func,
|
|
+ &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, czb);
|
|
+ if (err != 0) {
|
|
+ /*
|
|
+ * If both TRAVERSE_HARD and TRAVERSE_PRE are set,
|
|
+ * continue to visitbp so that td_func can be called
|
|
+ * in pre stage, and err will reset to zero.
|
|
+ */
|
|
+ if (!(td->td_flags & TRAVERSE_HARD) ||
|
|
+ !(td->td_flags & TRAVERSE_PRE))
|
|
+ return (err);
|
|
+ } else {
|
|
+ osp = buf->b_data;
|
|
+ traverse_zil(td, &osp->os_zil_header);
|
|
+ arc_buf_destroy(buf, &buf);
|
|
+ }
|
|
}
|
|
|
|
if (!(flags & TRAVERSE_PREFETCH_DATA) ||
|
|
--
|
|
2.14.2
|
|
|