1cafe5635SKent Overstreet /* 2cafe5635SKent Overstreet * Assorted bcache debug code 3cafe5635SKent Overstreet * 4cafe5635SKent Overstreet * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com> 5cafe5635SKent Overstreet * Copyright 2012 Google, Inc. 6cafe5635SKent Overstreet */ 7cafe5635SKent Overstreet 8cafe5635SKent Overstreet #include "bcache.h" 9cafe5635SKent Overstreet #include "btree.h" 10cafe5635SKent Overstreet #include "debug.h" 11cafe5635SKent Overstreet 12cafe5635SKent Overstreet #include <linux/console.h> 13cafe5635SKent Overstreet #include <linux/debugfs.h> 14cafe5635SKent Overstreet #include <linux/module.h> 15cafe5635SKent Overstreet #include <linux/random.h> 16cafe5635SKent Overstreet #include <linux/seq_file.h> 17cafe5635SKent Overstreet 18cafe5635SKent Overstreet static struct dentry *debug; 19cafe5635SKent Overstreet 20cafe5635SKent Overstreet const char *bch_ptr_status(struct cache_set *c, const struct bkey *k) 21cafe5635SKent Overstreet { 22cafe5635SKent Overstreet unsigned i; 23cafe5635SKent Overstreet 24cafe5635SKent Overstreet for (i = 0; i < KEY_PTRS(k); i++) 25cafe5635SKent Overstreet if (ptr_available(c, k, i)) { 26cafe5635SKent Overstreet struct cache *ca = PTR_CACHE(c, k, i); 27cafe5635SKent Overstreet size_t bucket = PTR_BUCKET_NR(c, k, i); 28cafe5635SKent Overstreet size_t r = bucket_remainder(c, PTR_OFFSET(k, i)); 29cafe5635SKent Overstreet 30cafe5635SKent Overstreet if (KEY_SIZE(k) + r > c->sb.bucket_size) 31cafe5635SKent Overstreet return "bad, length too big"; 32cafe5635SKent Overstreet if (bucket < ca->sb.first_bucket) 33cafe5635SKent Overstreet return "bad, short offset"; 34cafe5635SKent Overstreet if (bucket >= ca->sb.nbuckets) 35cafe5635SKent Overstreet return "bad, offset past end of device"; 36cafe5635SKent Overstreet if (ptr_stale(c, k, i)) 37cafe5635SKent Overstreet return "stale"; 38cafe5635SKent Overstreet } 39cafe5635SKent Overstreet 40cafe5635SKent Overstreet if (!bkey_cmp(k, &ZERO_KEY)) 41cafe5635SKent Overstreet return "bad, null key"; 42cafe5635SKent Overstreet if (!KEY_PTRS(k)) 43cafe5635SKent Overstreet return "bad, no pointers"; 44cafe5635SKent Overstreet if (!KEY_SIZE(k)) 45cafe5635SKent Overstreet return "zeroed key"; 46cafe5635SKent Overstreet return ""; 47cafe5635SKent Overstreet } 48cafe5635SKent Overstreet 4985b1492eSKent Overstreet int bch_bkey_to_text(char *buf, size_t size, const struct bkey *k) 50cafe5635SKent Overstreet { 51cafe5635SKent Overstreet unsigned i = 0; 5285b1492eSKent Overstreet char *out = buf, *end = buf + size; 53cafe5635SKent Overstreet 54cafe5635SKent Overstreet #define p(...) (out += scnprintf(out, end - out, __VA_ARGS__)) 55cafe5635SKent Overstreet 56cafe5635SKent Overstreet p("%llu:%llu len %llu -> [", KEY_INODE(k), KEY_OFFSET(k), KEY_SIZE(k)); 57cafe5635SKent Overstreet 58cafe5635SKent Overstreet if (KEY_PTRS(k)) 59cafe5635SKent Overstreet while (1) { 60cafe5635SKent Overstreet p("%llu:%llu gen %llu", 61cafe5635SKent Overstreet PTR_DEV(k, i), PTR_OFFSET(k, i), PTR_GEN(k, i)); 62cafe5635SKent Overstreet 63cafe5635SKent Overstreet if (++i == KEY_PTRS(k)) 64cafe5635SKent Overstreet break; 65cafe5635SKent Overstreet 66cafe5635SKent Overstreet p(", "); 67cafe5635SKent Overstreet } 68cafe5635SKent Overstreet 69cafe5635SKent Overstreet p("]"); 70cafe5635SKent Overstreet 71cafe5635SKent Overstreet if (KEY_DIRTY(k)) 72cafe5635SKent Overstreet p(" dirty"); 73cafe5635SKent Overstreet if (KEY_CSUM(k)) 74cafe5635SKent Overstreet p(" cs%llu %llx", KEY_CSUM(k), k->ptr[1]); 75cafe5635SKent Overstreet #undef p 7685b1492eSKent Overstreet return out - buf; 77cafe5635SKent Overstreet } 78cafe5635SKent Overstreet 79280481d0SKent Overstreet #ifdef CONFIG_BCACHE_DEBUG 80cafe5635SKent Overstreet 81cafe5635SKent Overstreet static void dump_bset(struct btree *b, struct bset *i) 82cafe5635SKent Overstreet { 83280481d0SKent Overstreet struct bkey *k, *next; 84cafe5635SKent Overstreet unsigned j; 8585b1492eSKent Overstreet char buf[80]; 86cafe5635SKent Overstreet 87280481d0SKent Overstreet for (k = i->start; k < end(i); k = next) { 88280481d0SKent Overstreet next = bkey_next(k); 89280481d0SKent Overstreet 9085b1492eSKent Overstreet bch_bkey_to_text(buf, sizeof(buf), k); 91cafe5635SKent Overstreet printk(KERN_ERR "block %zu key %zi/%u: %s", index(i, b), 9285b1492eSKent Overstreet (uint64_t *) k - i->d, i->keys, buf); 93cafe5635SKent Overstreet 94cafe5635SKent Overstreet for (j = 0; j < KEY_PTRS(k); j++) { 95cafe5635SKent Overstreet size_t n = PTR_BUCKET_NR(b->c, k, j); 96cafe5635SKent Overstreet printk(" bucket %zu", n); 97cafe5635SKent Overstreet 98cafe5635SKent Overstreet if (n >= b->c->sb.first_bucket && n < b->c->sb.nbuckets) 99cafe5635SKent Overstreet printk(" prio %i", 100cafe5635SKent Overstreet PTR_BUCKET(b->c, k, j)->prio); 101cafe5635SKent Overstreet } 102cafe5635SKent Overstreet 103cafe5635SKent Overstreet printk(" %s\n", bch_ptr_status(b->c, k)); 104cafe5635SKent Overstreet 105280481d0SKent Overstreet if (next < end(i) && 106280481d0SKent Overstreet bkey_cmp(k, !b->level ? &START_KEY(next) : next) > 0) 107cafe5635SKent Overstreet printk(KERN_ERR "Key skipped backwards\n"); 108cafe5635SKent Overstreet } 109cafe5635SKent Overstreet } 110cafe5635SKent Overstreet 111280481d0SKent Overstreet static void bch_dump_bucket(struct btree *b) 112280481d0SKent Overstreet { 113280481d0SKent Overstreet unsigned i; 114cafe5635SKent Overstreet 115280481d0SKent Overstreet console_lock(); 116280481d0SKent Overstreet for (i = 0; i <= b->nsets; i++) 117280481d0SKent Overstreet dump_bset(b, b->sets[i].data); 118280481d0SKent Overstreet console_unlock(); 119280481d0SKent Overstreet } 120cafe5635SKent Overstreet 121cafe5635SKent Overstreet void bch_btree_verify(struct btree *b, struct bset *new) 122cafe5635SKent Overstreet { 123cafe5635SKent Overstreet struct btree *v = b->c->verify_data; 124cafe5635SKent Overstreet struct closure cl; 125cafe5635SKent Overstreet closure_init_stack(&cl); 126cafe5635SKent Overstreet 127cafe5635SKent Overstreet if (!b->c->verify) 128cafe5635SKent Overstreet return; 129cafe5635SKent Overstreet 130cafe5635SKent Overstreet closure_wait_event(&b->io.wait, &cl, 131cafe5635SKent Overstreet atomic_read(&b->io.cl.remaining) == -1); 132cafe5635SKent Overstreet 133cafe5635SKent Overstreet mutex_lock(&b->c->verify_lock); 134cafe5635SKent Overstreet 135cafe5635SKent Overstreet bkey_copy(&v->key, &b->key); 136cafe5635SKent Overstreet v->written = 0; 137cafe5635SKent Overstreet v->level = b->level; 138cafe5635SKent Overstreet 13957943511SKent Overstreet bch_btree_node_read(v); 140cafe5635SKent Overstreet closure_wait_event(&v->io.wait, &cl, 141cafe5635SKent Overstreet atomic_read(&b->io.cl.remaining) == -1); 142cafe5635SKent Overstreet 143cafe5635SKent Overstreet if (new->keys != v->sets[0].data->keys || 144cafe5635SKent Overstreet memcmp(new->start, 145cafe5635SKent Overstreet v->sets[0].data->start, 146cafe5635SKent Overstreet (void *) end(new) - (void *) new->start)) { 147cafe5635SKent Overstreet unsigned i, j; 148cafe5635SKent Overstreet 149cafe5635SKent Overstreet console_lock(); 150cafe5635SKent Overstreet 151cafe5635SKent Overstreet printk(KERN_ERR "*** original memory node:\n"); 152cafe5635SKent Overstreet for (i = 0; i <= b->nsets; i++) 153cafe5635SKent Overstreet dump_bset(b, b->sets[i].data); 154cafe5635SKent Overstreet 155cafe5635SKent Overstreet printk(KERN_ERR "*** sorted memory node:\n"); 156cafe5635SKent Overstreet dump_bset(b, new); 157cafe5635SKent Overstreet 158cafe5635SKent Overstreet printk(KERN_ERR "*** on disk node:\n"); 159cafe5635SKent Overstreet dump_bset(v, v->sets[0].data); 160cafe5635SKent Overstreet 161cafe5635SKent Overstreet for (j = 0; j < new->keys; j++) 162cafe5635SKent Overstreet if (new->d[j] != v->sets[0].data->d[j]) 163cafe5635SKent Overstreet break; 164cafe5635SKent Overstreet 165cafe5635SKent Overstreet console_unlock(); 166cafe5635SKent Overstreet panic("verify failed at %u\n", j); 167cafe5635SKent Overstreet } 168cafe5635SKent Overstreet 169cafe5635SKent Overstreet mutex_unlock(&b->c->verify_lock); 170cafe5635SKent Overstreet } 171cafe5635SKent Overstreet 172220bb38cSKent Overstreet void bch_data_verify(struct cached_dev *dc, struct bio *bio) 173cafe5635SKent Overstreet { 174cafe5635SKent Overstreet char name[BDEVNAME_SIZE]; 175cafe5635SKent Overstreet struct bio *check; 176cafe5635SKent Overstreet struct bio_vec *bv; 177cafe5635SKent Overstreet int i; 178cafe5635SKent Overstreet 179220bb38cSKent Overstreet check = bio_clone(bio, GFP_NOIO); 180cafe5635SKent Overstreet if (!check) 181cafe5635SKent Overstreet return; 182cafe5635SKent Overstreet 1838e51e414SKent Overstreet if (bio_alloc_pages(check, GFP_NOIO)) 184cafe5635SKent Overstreet goto out_put; 185cafe5635SKent Overstreet 186220bb38cSKent Overstreet submit_bio_wait(READ_SYNC, check); 187cafe5635SKent Overstreet 188220bb38cSKent Overstreet bio_for_each_segment(bv, bio, i) { 189220bb38cSKent Overstreet void *p1 = kmap_atomic(bv->bv_page); 190220bb38cSKent Overstreet void *p2 = page_address(check->bi_io_vec[i].bv_page); 191cafe5635SKent Overstreet 1925ceaaad7SKent Overstreet cache_set_err_on(memcmp(p1 + bv->bv_offset, 193cafe5635SKent Overstreet p2 + bv->bv_offset, 1945ceaaad7SKent Overstreet bv->bv_len), 1955ceaaad7SKent Overstreet dc->disk.c, 1965ceaaad7SKent Overstreet "verify failed at dev %s sector %llu", 197cafe5635SKent Overstreet bdevname(dc->bdev, name), 198*4f024f37SKent Overstreet (uint64_t) bio->bi_iter.bi_sector); 1995ceaaad7SKent Overstreet 200220bb38cSKent Overstreet kunmap_atomic(p1); 201cafe5635SKent Overstreet } 202cafe5635SKent Overstreet 203220bb38cSKent Overstreet bio_for_each_segment_all(bv, check, i) 204cafe5635SKent Overstreet __free_page(bv->bv_page); 205cafe5635SKent Overstreet out_put: 206cafe5635SKent Overstreet bio_put(check); 207cafe5635SKent Overstreet } 208cafe5635SKent Overstreet 209280481d0SKent Overstreet int __bch_count_data(struct btree *b) 210cafe5635SKent Overstreet { 211cafe5635SKent Overstreet unsigned ret = 0; 212cafe5635SKent Overstreet struct btree_iter iter; 213cafe5635SKent Overstreet struct bkey *k; 214cafe5635SKent Overstreet 215cafe5635SKent Overstreet if (!b->level) 216cafe5635SKent Overstreet for_each_key(b, k, &iter) 217cafe5635SKent Overstreet ret += KEY_SIZE(k); 218cafe5635SKent Overstreet return ret; 219cafe5635SKent Overstreet } 220cafe5635SKent Overstreet 221280481d0SKent Overstreet void __bch_check_keys(struct btree *b, const char *fmt, ...) 222cafe5635SKent Overstreet { 223cafe5635SKent Overstreet va_list args; 224cafe5635SKent Overstreet struct bkey *k, *p = NULL; 225cafe5635SKent Overstreet struct btree_iter iter; 226280481d0SKent Overstreet const char *err; 227cafe5635SKent Overstreet 228cafe5635SKent Overstreet for_each_key(b, k, &iter) { 229280481d0SKent Overstreet if (!b->level) { 230280481d0SKent Overstreet err = "Keys out of order"; 231280481d0SKent Overstreet if (p && bkey_cmp(&START_KEY(p), &START_KEY(k)) > 0) 232cafe5635SKent Overstreet goto bug; 233cafe5635SKent Overstreet 234cafe5635SKent Overstreet if (bch_ptr_invalid(b, k)) 235cafe5635SKent Overstreet continue; 236cafe5635SKent Overstreet 237280481d0SKent Overstreet err = "Overlapping keys"; 238280481d0SKent Overstreet if (p && bkey_cmp(p, &START_KEY(k)) > 0) 239280481d0SKent Overstreet goto bug; 240280481d0SKent Overstreet } else { 241280481d0SKent Overstreet if (bch_ptr_bad(b, k)) 242280481d0SKent Overstreet continue; 243280481d0SKent Overstreet 244280481d0SKent Overstreet err = "Duplicate keys"; 245280481d0SKent Overstreet if (p && !bkey_cmp(p, k)) 246cafe5635SKent Overstreet goto bug; 247cafe5635SKent Overstreet } 248cafe5635SKent Overstreet p = k; 249cafe5635SKent Overstreet } 250280481d0SKent Overstreet 251280481d0SKent Overstreet err = "Key larger than btree node key"; 252280481d0SKent Overstreet if (p && bkey_cmp(p, &b->key) > 0) 253280481d0SKent Overstreet goto bug; 254280481d0SKent Overstreet 255cafe5635SKent Overstreet return; 256cafe5635SKent Overstreet bug: 257280481d0SKent Overstreet bch_dump_bucket(b); 258280481d0SKent Overstreet 259cafe5635SKent Overstreet va_start(args, fmt); 260280481d0SKent Overstreet vprintk(fmt, args); 261cafe5635SKent Overstreet va_end(args); 262280481d0SKent Overstreet 263280481d0SKent Overstreet panic("bcache error: %s:\n", err); 264280481d0SKent Overstreet } 265280481d0SKent Overstreet 266280481d0SKent Overstreet void bch_btree_iter_next_check(struct btree_iter *iter) 267280481d0SKent Overstreet { 268280481d0SKent Overstreet struct bkey *k = iter->data->k, *next = bkey_next(k); 269280481d0SKent Overstreet 270280481d0SKent Overstreet if (next < iter->data->end && 271280481d0SKent Overstreet bkey_cmp(k, iter->b->level ? next : &START_KEY(next)) > 0) { 272280481d0SKent Overstreet bch_dump_bucket(iter->b); 273280481d0SKent Overstreet panic("Key skipped backwards\n"); 274280481d0SKent Overstreet } 275cafe5635SKent Overstreet } 276cafe5635SKent Overstreet 277cafe5635SKent Overstreet #endif 278cafe5635SKent Overstreet 279cafe5635SKent Overstreet #ifdef CONFIG_DEBUG_FS 280cafe5635SKent Overstreet 281cafe5635SKent Overstreet /* XXX: cache set refcounting */ 282cafe5635SKent Overstreet 283cafe5635SKent Overstreet struct dump_iterator { 284cafe5635SKent Overstreet char buf[PAGE_SIZE]; 285cafe5635SKent Overstreet size_t bytes; 286cafe5635SKent Overstreet struct cache_set *c; 287cafe5635SKent Overstreet struct keybuf keys; 288cafe5635SKent Overstreet }; 289cafe5635SKent Overstreet 290cafe5635SKent Overstreet static bool dump_pred(struct keybuf *buf, struct bkey *k) 291cafe5635SKent Overstreet { 292cafe5635SKent Overstreet return true; 293cafe5635SKent Overstreet } 294cafe5635SKent Overstreet 295cafe5635SKent Overstreet static ssize_t bch_dump_read(struct file *file, char __user *buf, 296cafe5635SKent Overstreet size_t size, loff_t *ppos) 297cafe5635SKent Overstreet { 298cafe5635SKent Overstreet struct dump_iterator *i = file->private_data; 299cafe5635SKent Overstreet ssize_t ret = 0; 30085b1492eSKent Overstreet char kbuf[80]; 301cafe5635SKent Overstreet 302cafe5635SKent Overstreet while (size) { 303cafe5635SKent Overstreet struct keybuf_key *w; 304cafe5635SKent Overstreet unsigned bytes = min(i->bytes, size); 305cafe5635SKent Overstreet 306cafe5635SKent Overstreet int err = copy_to_user(buf, i->buf, bytes); 307cafe5635SKent Overstreet if (err) 308cafe5635SKent Overstreet return err; 309cafe5635SKent Overstreet 310cafe5635SKent Overstreet ret += bytes; 311cafe5635SKent Overstreet buf += bytes; 312cafe5635SKent Overstreet size -= bytes; 313cafe5635SKent Overstreet i->bytes -= bytes; 314cafe5635SKent Overstreet memmove(i->buf, i->buf + bytes, i->bytes); 315cafe5635SKent Overstreet 316cafe5635SKent Overstreet if (i->bytes) 317cafe5635SKent Overstreet break; 318cafe5635SKent Overstreet 31972c27061SKent Overstreet w = bch_keybuf_next_rescan(i->c, &i->keys, &MAX_KEY, dump_pred); 320cafe5635SKent Overstreet if (!w) 321cafe5635SKent Overstreet break; 322cafe5635SKent Overstreet 32385b1492eSKent Overstreet bch_bkey_to_text(kbuf, sizeof(kbuf), &w->key); 32485b1492eSKent Overstreet i->bytes = snprintf(i->buf, PAGE_SIZE, "%s\n", kbuf); 325cafe5635SKent Overstreet bch_keybuf_del(&i->keys, w); 326cafe5635SKent Overstreet } 327cafe5635SKent Overstreet 328cafe5635SKent Overstreet return ret; 329cafe5635SKent Overstreet } 330cafe5635SKent Overstreet 331cafe5635SKent Overstreet static int bch_dump_open(struct inode *inode, struct file *file) 332cafe5635SKent Overstreet { 333cafe5635SKent Overstreet struct cache_set *c = inode->i_private; 334cafe5635SKent Overstreet struct dump_iterator *i; 335cafe5635SKent Overstreet 336cafe5635SKent Overstreet i = kzalloc(sizeof(struct dump_iterator), GFP_KERNEL); 337cafe5635SKent Overstreet if (!i) 338cafe5635SKent Overstreet return -ENOMEM; 339cafe5635SKent Overstreet 340cafe5635SKent Overstreet file->private_data = i; 341cafe5635SKent Overstreet i->c = c; 34272c27061SKent Overstreet bch_keybuf_init(&i->keys); 343cafe5635SKent Overstreet i->keys.last_scanned = KEY(0, 0, 0); 344cafe5635SKent Overstreet 345cafe5635SKent Overstreet return 0; 346cafe5635SKent Overstreet } 347cafe5635SKent Overstreet 348cafe5635SKent Overstreet static int bch_dump_release(struct inode *inode, struct file *file) 349cafe5635SKent Overstreet { 350cafe5635SKent Overstreet kfree(file->private_data); 351cafe5635SKent Overstreet return 0; 352cafe5635SKent Overstreet } 353cafe5635SKent Overstreet 354cafe5635SKent Overstreet static const struct file_operations cache_set_debug_ops = { 355cafe5635SKent Overstreet .owner = THIS_MODULE, 356cafe5635SKent Overstreet .open = bch_dump_open, 357cafe5635SKent Overstreet .read = bch_dump_read, 358cafe5635SKent Overstreet .release = bch_dump_release 359cafe5635SKent Overstreet }; 360cafe5635SKent Overstreet 361cafe5635SKent Overstreet void bch_debug_init_cache_set(struct cache_set *c) 362cafe5635SKent Overstreet { 363cafe5635SKent Overstreet if (!IS_ERR_OR_NULL(debug)) { 364cafe5635SKent Overstreet char name[50]; 365cafe5635SKent Overstreet snprintf(name, 50, "bcache-%pU", c->sb.set_uuid); 366cafe5635SKent Overstreet 367cafe5635SKent Overstreet c->debug = debugfs_create_file(name, 0400, debug, c, 368cafe5635SKent Overstreet &cache_set_debug_ops); 369cafe5635SKent Overstreet } 370cafe5635SKent Overstreet } 371cafe5635SKent Overstreet 372cafe5635SKent Overstreet #endif 373cafe5635SKent Overstreet 374cafe5635SKent Overstreet void bch_debug_exit(void) 375cafe5635SKent Overstreet { 376cafe5635SKent Overstreet if (!IS_ERR_OR_NULL(debug)) 377cafe5635SKent Overstreet debugfs_remove_recursive(debug); 378cafe5635SKent Overstreet } 379cafe5635SKent Overstreet 380cafe5635SKent Overstreet int __init bch_debug_init(struct kobject *kobj) 381cafe5635SKent Overstreet { 382cafe5635SKent Overstreet int ret = 0; 383cafe5635SKent Overstreet 384cafe5635SKent Overstreet debug = debugfs_create_dir("bcache", NULL); 385cafe5635SKent Overstreet return ret; 386cafe5635SKent Overstreet } 387