diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-12-18 02:47:33 -0500 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-01-08 16:05:13 -0500 |
commit | dc9d98d621bdce0552997200ce855659875a5c9f (patch) | |
tree | d0339299ab01f50dd225446734a7d34164df2817 /drivers/md/bcache/debug.c | |
parent | c052dd9a26f60bcf70c0c3fcc08e07abb60295cd (diff) |
bcache: Convert debug code to btree_keys
More work to disentangle various code from struct btree
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md/bcache/debug.c')
-rw-r--r-- | drivers/md/bcache/debug.c | 179 |
1 files changed, 5 insertions, 174 deletions
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c index 3de27e2a4e07..8b1f1d5c1819 100644 --- a/drivers/md/bcache/debug.c +++ b/drivers/md/bcache/debug.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "bcache.h" | 8 | #include "bcache.h" |
9 | #include "btree.h" | 9 | #include "btree.h" |
10 | #include "debug.h" | 10 | #include "debug.h" |
11 | #include "extents.h" | ||
11 | 12 | ||
12 | #include <linux/console.h> | 13 | #include <linux/console.h> |
13 | #include <linux/debugfs.h> | 14 | #include <linux/debugfs.h> |
@@ -17,108 +18,8 @@ | |||
17 | 18 | ||
18 | static struct dentry *debug; | 19 | static struct dentry *debug; |
19 | 20 | ||
20 | const char *bch_ptr_status(struct cache_set *c, const struct bkey *k) | ||
21 | { | ||
22 | unsigned i; | ||
23 | |||
24 | for (i = 0; i < KEY_PTRS(k); i++) | ||
25 | if (ptr_available(c, k, i)) { | ||
26 | struct cache *ca = PTR_CACHE(c, k, i); | ||
27 | size_t bucket = PTR_BUCKET_NR(c, k, i); | ||
28 | size_t r = bucket_remainder(c, PTR_OFFSET(k, i)); | ||
29 | |||
30 | if (KEY_SIZE(k) + r > c->sb.bucket_size) | ||
31 | return "bad, length too big"; | ||
32 | if (bucket < ca->sb.first_bucket) | ||
33 | return "bad, short offset"; | ||
34 | if (bucket >= ca->sb.nbuckets) | ||
35 | return "bad, offset past end of device"; | ||
36 | if (ptr_stale(c, k, i)) | ||
37 | return "stale"; | ||
38 | } | ||
39 | |||
40 | if (!bkey_cmp(k, &ZERO_KEY)) | ||
41 | return "bad, null key"; | ||
42 | if (!KEY_PTRS(k)) | ||
43 | return "bad, no pointers"; | ||
44 | if (!KEY_SIZE(k)) | ||
45 | return "zeroed key"; | ||
46 | return ""; | ||
47 | } | ||
48 | |||
49 | int bch_bkey_to_text(char *buf, size_t size, const struct bkey *k) | ||
50 | { | ||
51 | unsigned i = 0; | ||
52 | char *out = buf, *end = buf + size; | ||
53 | |||
54 | #define p(...) (out += scnprintf(out, end - out, __VA_ARGS__)) | ||
55 | |||
56 | p("%llu:%llu len %llu -> [", KEY_INODE(k), KEY_START(k), KEY_SIZE(k)); | ||
57 | |||
58 | for (i = 0; i < KEY_PTRS(k); i++) { | ||
59 | if (i) | ||
60 | p(", "); | ||
61 | |||
62 | if (PTR_DEV(k, i) == PTR_CHECK_DEV) | ||
63 | p("check dev"); | ||
64 | else | ||
65 | p("%llu:%llu gen %llu", PTR_DEV(k, i), | ||
66 | PTR_OFFSET(k, i), PTR_GEN(k, i)); | ||
67 | } | ||
68 | |||
69 | p("]"); | ||
70 | |||
71 | if (KEY_DIRTY(k)) | ||
72 | p(" dirty"); | ||
73 | if (KEY_CSUM(k)) | ||
74 | p(" cs%llu %llx", KEY_CSUM(k), k->ptr[1]); | ||
75 | #undef p | ||
76 | return out - buf; | ||
77 | } | ||
78 | |||
79 | #ifdef CONFIG_BCACHE_DEBUG | 21 | #ifdef CONFIG_BCACHE_DEBUG |
80 | 22 | ||
81 | static void dump_bset(struct btree *b, struct bset *i, unsigned set) | ||
82 | { | ||
83 | struct bkey *k, *next; | ||
84 | unsigned j; | ||
85 | char buf[80]; | ||
86 | |||
87 | for (k = i->start; k < bset_bkey_last(i); k = next) { | ||
88 | next = bkey_next(k); | ||
89 | |||
90 | bch_bkey_to_text(buf, sizeof(buf), k); | ||
91 | printk(KERN_ERR "b %u k %zi/%u: %s", set, | ||
92 | (uint64_t *) k - i->d, i->keys, buf); | ||
93 | |||
94 | for (j = 0; j < KEY_PTRS(k); j++) { | ||
95 | size_t n = PTR_BUCKET_NR(b->c, k, j); | ||
96 | printk(" bucket %zu", n); | ||
97 | |||
98 | if (n >= b->c->sb.first_bucket && n < b->c->sb.nbuckets) | ||
99 | printk(" prio %i", | ||
100 | PTR_BUCKET(b->c, k, j)->prio); | ||
101 | } | ||
102 | |||
103 | printk(" %s\n", bch_ptr_status(b->c, k)); | ||
104 | |||
105 | if (next < bset_bkey_last(i) && | ||
106 | bkey_cmp(k, !b->level ? &START_KEY(next) : next) > 0) | ||
107 | printk(KERN_ERR "Key skipped backwards\n"); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static void bch_dump_bucket(struct btree *b) | ||
112 | { | ||
113 | unsigned i; | ||
114 | |||
115 | console_lock(); | ||
116 | for (i = 0; i <= b->keys.nsets; i++) | ||
117 | dump_bset(b, b->keys.set[i].data, | ||
118 | bset_block_offset(b, b->keys.set[i].data)); | ||
119 | console_unlock(); | ||
120 | } | ||
121 | |||
122 | #define for_each_written_bset(b, start, i) \ | 23 | #define for_each_written_bset(b, start, i) \ |
123 | for (i = (start); \ | 24 | for (i = (start); \ |
124 | (void *) i < (void *) (start) + (KEY_SIZE(&b->key) << 9) &&\ | 25 | (void *) i < (void *) (start) + (KEY_SIZE(&b->key) << 9) &&\ |
@@ -171,17 +72,17 @@ void bch_btree_verify(struct btree *b) | |||
171 | console_lock(); | 72 | console_lock(); |
172 | 73 | ||
173 | printk(KERN_ERR "*** in memory:\n"); | 74 | printk(KERN_ERR "*** in memory:\n"); |
174 | dump_bset(b, inmemory, 0); | 75 | bch_dump_bset(&b->keys, inmemory, 0); |
175 | 76 | ||
176 | printk(KERN_ERR "*** read back in:\n"); | 77 | printk(KERN_ERR "*** read back in:\n"); |
177 | dump_bset(v, sorted, 0); | 78 | bch_dump_bset(&v->keys, sorted, 0); |
178 | 79 | ||
179 | for_each_written_bset(b, ondisk, i) { | 80 | for_each_written_bset(b, ondisk, i) { |
180 | unsigned block = ((void *) i - (void *) ondisk) / | 81 | unsigned block = ((void *) i - (void *) ondisk) / |
181 | block_bytes(b->c); | 82 | block_bytes(b->c); |
182 | 83 | ||
183 | printk(KERN_ERR "*** on disk block %u:\n", block); | 84 | printk(KERN_ERR "*** on disk block %u:\n", block); |
184 | dump_bset(b, i, block); | 85 | bch_dump_bset(&b->keys, i, block); |
185 | } | 86 | } |
186 | 87 | ||
187 | printk(KERN_ERR "*** block %zu not written\n", | 88 | printk(KERN_ERR "*** block %zu not written\n", |
@@ -239,76 +140,6 @@ out_put: | |||
239 | bio_put(check); | 140 | bio_put(check); |
240 | } | 141 | } |
241 | 142 | ||
242 | int __bch_count_data(struct btree *b) | ||
243 | { | ||
244 | unsigned ret = 0; | ||
245 | struct btree_iter iter; | ||
246 | struct bkey *k; | ||
247 | |||
248 | if (!b->level) | ||
249 | for_each_key(&b->keys, k, &iter) | ||
250 | ret += KEY_SIZE(k); | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | void __bch_check_keys(struct btree *b, const char *fmt, ...) | ||
255 | { | ||
256 | va_list args; | ||
257 | struct bkey *k, *p = NULL; | ||
258 | struct btree_iter iter; | ||
259 | const char *err; | ||
260 | |||
261 | for_each_key(&b->keys, k, &iter) { | ||
262 | if (!b->level) { | ||
263 | err = "Keys out of order"; | ||
264 | if (p && bkey_cmp(&START_KEY(p), &START_KEY(k)) > 0) | ||
265 | goto bug; | ||
266 | |||
267 | if (bch_ptr_invalid(&b->keys, k)) | ||
268 | continue; | ||
269 | |||
270 | err = "Overlapping keys"; | ||
271 | if (p && bkey_cmp(p, &START_KEY(k)) > 0) | ||
272 | goto bug; | ||
273 | } else { | ||
274 | if (bch_ptr_bad(&b->keys, k)) | ||
275 | continue; | ||
276 | |||
277 | err = "Duplicate keys"; | ||
278 | if (p && !bkey_cmp(p, k)) | ||
279 | goto bug; | ||
280 | } | ||
281 | p = k; | ||
282 | } | ||
283 | |||
284 | err = "Key larger than btree node key"; | ||
285 | if (p && bkey_cmp(p, &b->key) > 0) | ||
286 | goto bug; | ||
287 | |||
288 | return; | ||
289 | bug: | ||
290 | bch_dump_bucket(b); | ||
291 | |||
292 | va_start(args, fmt); | ||
293 | vprintk(fmt, args); | ||
294 | va_end(args); | ||
295 | |||
296 | panic("bcache error: %s:\n", err); | ||
297 | } | ||
298 | |||
299 | void bch_btree_iter_next_check(struct btree_iter *iter) | ||
300 | { | ||
301 | #if 0 | ||
302 | struct bkey *k = iter->data->k, *next = bkey_next(k); | ||
303 | |||
304 | if (next < iter->data->end && | ||
305 | bkey_cmp(k, iter->b->level ? next : &START_KEY(next)) > 0) { | ||
306 | bch_dump_bucket(iter->b); | ||
307 | panic("Key skipped backwards\n"); | ||
308 | } | ||
309 | #endif | ||
310 | } | ||
311 | |||
312 | #endif | 143 | #endif |
313 | 144 | ||
314 | #ifdef CONFIG_DEBUG_FS | 145 | #ifdef CONFIG_DEBUG_FS |
@@ -355,7 +186,7 @@ static ssize_t bch_dump_read(struct file *file, char __user *buf, | |||
355 | if (!w) | 186 | if (!w) |
356 | break; | 187 | break; |
357 | 188 | ||
358 | bch_bkey_to_text(kbuf, sizeof(kbuf), &w->key); | 189 | bch_extent_to_text(kbuf, sizeof(kbuf), &w->key); |
359 | i->bytes = snprintf(i->buf, PAGE_SIZE, "%s\n", kbuf); | 190 | i->bytes = snprintf(i->buf, PAGE_SIZE, "%s\n", kbuf); |
360 | bch_keybuf_del(&i->keys, w); | 191 | bch_keybuf_del(&i->keys, w); |
361 | } | 192 | } |