]> git.proxmox.com Git - zfsonlinux.git/blame - zfs-patches/0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch
update SPL to 0.7.7
[zfsonlinux.git] / zfs-patches / 0022-Fix-zdb-c-traverse-stop-on-damaged-objset-root.patch
CommitLineData
75b07eca
FG
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Chunwei Chen <david.chen@nutanix.com>
3Date: Tue, 30 Jan 2018 13:39:11 -0800
4Subject: [PATCH] Fix zdb -c traverse stop on damaged objset root
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9If a corruption happens to be on a root block of an objset, zdb -c will
10not correctly report the error, and it will not traverse the datasets
11that come after. This is because traverse_visitbp, which does the
12callback and reset error for TRAVERSE_HARD, is skipped when traversing
13zil is failed in traverse_impl.
14
15Here's example of what 'zdb -eLcc' command looks like on a pool with
16damaged objset root:
17
18== before patch:
19
20Traversing all blocks to verify checksums ...
21
22Error counts:
23
24 errno count
25block traversal size 379392 != alloc 33987072 (unreachable 33607680)
26
27 bp count: 172
28 ganged count: 0
29 bp logical: 1678336 avg: 9757
30 bp physical: 130560 avg: 759 compression: 12.85
31 bp allocated: 379392 avg: 2205 compression: 4.42
32 bp deduped: 0 ref>1: 0 deduplication: 1.00
33 SPA allocated: 33987072 used: 0.80%
34
35 additional, non-pointer bps of type 0: 71
36 Dittoed blocks on same vdev: 101
37
38== after patch:
39
40Traversing all blocks to verify checksums ...
41
42zdb_blkptr_cb: Got error 52 reading <54, 0, -1, 0> -- skipping
43
44Error counts:
45
46 errno count
47 52 1
48block traversal size 33963520 != alloc 33987072 (unreachable 23552)
49
50 bp count: 447
51 ganged count: 0
52 bp logical: 36093440 avg: 80745
53 bp physical: 33699840 avg: 75391 compression: 1.07
54 bp allocated: 33963520 avg: 75981 compression: 1.06
55 bp deduped: 0 ref>1: 0 deduplication: 1.00
56 SPA allocated: 33987072 used: 0.80%
57
58 additional, non-pointer bps of type 0: 76
59 Dittoed blocks on same vdev: 115
60
61==
62
63Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
64Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
65Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
66Closes #7099
67(cherry picked from commit 23227313a2016449176cbfcbae2d4fc463a2bc09)
68Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
69---
70 module/zfs/dmu_traverse.c | 26 +++++++++++++++++---------
71 1 file changed, 17 insertions(+), 9 deletions(-)
72
73diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c
74index c78228d74..b494bef35 100644
75--- a/module/zfs/dmu_traverse.c
76+++ b/module/zfs/dmu_traverse.c
77@@ -599,19 +599,27 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp,
78
79 /* See comment on ZIL traversal in dsl_scan_visitds. */
80 if (ds != NULL && !ds->ds_is_snapshot && !BP_IS_HOLE(rootbp)) {
81+ enum zio_flag zio_flags = ZIO_FLAG_CANFAIL;
82 uint32_t flags = ARC_FLAG_WAIT;
83 objset_phys_t *osp;
84 arc_buf_t *buf;
85
86- err = arc_read(NULL, td->td_spa, rootbp,
87- arc_getbuf_func, &buf,
88- ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, czb);
89- if (err != 0)
90- return (err);
91-
92- osp = buf->b_data;
93- traverse_zil(td, &osp->os_zil_header);
94- arc_buf_destroy(buf, &buf);
95+ err = arc_read(NULL, td->td_spa, rootbp, arc_getbuf_func,
96+ &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, czb);
97+ if (err != 0) {
98+ /*
99+ * If both TRAVERSE_HARD and TRAVERSE_PRE are set,
100+ * continue to visitbp so that td_func can be called
101+ * in pre stage, and err will reset to zero.
102+ */
103+ if (!(td->td_flags & TRAVERSE_HARD) ||
104+ !(td->td_flags & TRAVERSE_PRE))
105+ return (err);
106+ } else {
107+ osp = buf->b_data;
108+ traverse_zil(td, &osp->os_zil_header);
109+ arc_buf_destroy(buf, &buf);
110+ }
111 }
112
113 if (!(flags & TRAVERSE_PREFETCH_DATA) ||
114--
1152.14.2
116