]> git.proxmox.com Git - zfsonlinux.git/blob - 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
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Chunwei Chen <david.chen@nutanix.com>
3 Date: Tue, 30 Jan 2018 13:39:11 -0800
4 Subject: [PATCH] Fix zdb -c traverse stop on damaged objset root
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 If a corruption happens to be on a root block of an objset, zdb -c will
10 not correctly report the error, and it will not traverse the datasets
11 that come after. This is because traverse_visitbp, which does the
12 callback and reset error for TRAVERSE_HARD, is skipped when traversing
13 zil is failed in traverse_impl.
14
15 Here's example of what 'zdb -eLcc' command looks like on a pool with
16 damaged objset root:
17
18 == before patch:
19
20 Traversing all blocks to verify checksums ...
21
22 Error counts:
23
24 errno count
25 block 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
40 Traversing all blocks to verify checksums ...
41
42 zdb_blkptr_cb: Got error 52 reading <54, 0, -1, 0> -- skipping
43
44 Error counts:
45
46 errno count
47 52 1
48 block 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
63 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
64 Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
65 Signed-off-by: Chunwei Chen <david.chen@nutanix.com>
66 Closes #7099
67 (cherry picked from commit 23227313a2016449176cbfcbae2d4fc463a2bc09)
68 Signed-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
73 diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c
74 index 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 --
115 2.14.2
116