1 // SPDX-License-Identifier: GPL-2.0
3 * Assorted bcache debug code
5 * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com>
6 * Copyright 2012 Google, Inc.
14 #include <linux/console.h>
15 #include <linux/debugfs.h>
16 #include <linux/module.h>
17 #include <linux/random.h>
18 #include <linux/seq_file.h>
20 static struct dentry
*debug
;
22 #ifdef CONFIG_BCACHE_DEBUG
24 #define for_each_written_bset(b, start, i) \
26 (void *) i < (void *) (start) + (KEY_SIZE(&b->key) << 9) &&\
27 i->seq == (start)->seq; \
28 i = (void *) i + set_blocks(i, block_bytes(b->c)) * \
31 void bch_btree_verify(struct btree
*b
)
33 struct btree
*v
= b
->c
->verify_data
;
34 struct bset
*ondisk
, *sorted
, *inmemory
;
37 if (!b
->c
->verify
|| !b
->c
->verify_ondisk
)
41 mutex_lock(&b
->c
->verify_lock
);
43 ondisk
= b
->c
->verify_ondisk
;
44 sorted
= b
->c
->verify_data
->keys
.set
->data
;
45 inmemory
= b
->keys
.set
->data
;
47 bkey_copy(&v
->key
, &b
->key
);
50 v
->keys
.ops
= b
->keys
.ops
;
52 bio
= bch_bbio_alloc(b
->c
);
53 bio_set_dev(bio
, PTR_CACHE(b
->c
, &b
->key
, 0)->bdev
);
54 bio
->bi_iter
.bi_sector
= PTR_OFFSET(&b
->key
, 0);
55 bio
->bi_iter
.bi_size
= KEY_SIZE(&v
->key
) << 9;
56 bio
->bi_opf
= REQ_OP_READ
| REQ_META
;
57 bch_bio_map(bio
, sorted
);
60 bch_bbio_free(bio
, b
->c
);
62 memcpy(ondisk
, sorted
, KEY_SIZE(&v
->key
) << 9);
64 bch_btree_node_read_done(v
);
65 sorted
= v
->keys
.set
->data
;
67 if (inmemory
->keys
!= sorted
->keys
||
68 memcmp(inmemory
->start
,
70 (void *) bset_bkey_last(inmemory
) - (void *) inmemory
->start
)) {
76 printk(KERN_ERR
"*** in memory:\n");
77 bch_dump_bset(&b
->keys
, inmemory
, 0);
79 printk(KERN_ERR
"*** read back in:\n");
80 bch_dump_bset(&v
->keys
, sorted
, 0);
82 for_each_written_bset(b
, ondisk
, i
) {
83 unsigned block
= ((void *) i
- (void *) ondisk
) /
86 printk(KERN_ERR
"*** on disk block %u:\n", block
);
87 bch_dump_bset(&b
->keys
, i
, block
);
90 printk(KERN_ERR
"*** block %zu not written\n",
91 ((void *) i
- (void *) ondisk
) / block_bytes(b
->c
));
93 for (j
= 0; j
< inmemory
->keys
; j
++)
94 if (inmemory
->d
[j
] != sorted
->d
[j
])
97 printk(KERN_ERR
"b->written %u\n", b
->written
);
100 panic("verify failed at %u\n", j
);
103 mutex_unlock(&b
->c
->verify_lock
);
107 void bch_data_verify(struct cached_dev
*dc
, struct bio
*bio
)
109 char name
[BDEVNAME_SIZE
];
111 struct bio_vec bv
, cbv
;
112 struct bvec_iter iter
, citer
= { 0 };
114 check
= bio_clone_kmalloc(bio
, GFP_NOIO
);
117 check
->bi_opf
= REQ_OP_READ
;
119 if (bch_bio_alloc_pages(check
, GFP_NOIO
))
122 submit_bio_wait(check
);
124 citer
.bi_size
= UINT_MAX
;
125 bio_for_each_segment(bv
, bio
, iter
) {
126 void *p1
= kmap_atomic(bv
.bv_page
);
129 cbv
= bio_iter_iovec(check
, citer
);
130 p2
= page_address(cbv
.bv_page
);
132 cache_set_err_on(memcmp(p1
+ bv
.bv_offset
,
136 "verify failed at dev %s sector %llu",
137 bdevname(dc
->bdev
, name
),
138 (uint64_t) bio
->bi_iter
.bi_sector
);
141 bio_advance_iter(check
, &citer
, bv
.bv_len
);
144 bio_free_pages(check
);
151 #ifdef CONFIG_DEBUG_FS
153 /* XXX: cache set refcounting */
155 struct dump_iterator
{
162 static bool dump_pred(struct keybuf
*buf
, struct bkey
*k
)
167 static ssize_t
bch_dump_read(struct file
*file
, char __user
*buf
,
168 size_t size
, loff_t
*ppos
)
170 struct dump_iterator
*i
= file
->private_data
;
175 struct keybuf_key
*w
;
176 unsigned bytes
= min(i
->bytes
, size
);
178 int err
= copy_to_user(buf
, i
->buf
, bytes
);
186 memmove(i
->buf
, i
->buf
+ bytes
, i
->bytes
);
191 w
= bch_keybuf_next_rescan(i
->c
, &i
->keys
, &MAX_KEY
, dump_pred
);
195 bch_extent_to_text(kbuf
, sizeof(kbuf
), &w
->key
);
196 i
->bytes
= snprintf(i
->buf
, PAGE_SIZE
, "%s\n", kbuf
);
197 bch_keybuf_del(&i
->keys
, w
);
203 static int bch_dump_open(struct inode
*inode
, struct file
*file
)
205 struct cache_set
*c
= inode
->i_private
;
206 struct dump_iterator
*i
;
208 i
= kzalloc(sizeof(struct dump_iterator
), GFP_KERNEL
);
212 file
->private_data
= i
;
214 bch_keybuf_init(&i
->keys
);
215 i
->keys
.last_scanned
= KEY(0, 0, 0);
220 static int bch_dump_release(struct inode
*inode
, struct file
*file
)
222 kfree(file
->private_data
);
226 static const struct file_operations cache_set_debug_ops
= {
227 .owner
= THIS_MODULE
,
228 .open
= bch_dump_open
,
229 .read
= bch_dump_read
,
230 .release
= bch_dump_release
233 void bch_debug_init_cache_set(struct cache_set
*c
)
235 if (!IS_ERR_OR_NULL(debug
)) {
237 snprintf(name
, 50, "bcache-%pU", c
->sb
.set_uuid
);
239 c
->debug
= debugfs_create_file(name
, 0400, debug
, c
,
240 &cache_set_debug_ops
);
246 void bch_debug_exit(void)
248 if (!IS_ERR_OR_NULL(debug
))
249 debugfs_remove_recursive(debug
);
252 int __init
bch_debug_init(struct kobject
*kobj
)
254 if (!IS_ENABLED(CONFIG_DEBUG_FS
))
257 debug
= debugfs_create_dir("bcache", NULL
);
259 return IS_ERR_OR_NULL(debug
);