bset.c (c052dd9a26f60bcf70c0c3fcc08e07abb60295cd) | bset.c (dc9d98d621bdce0552997200ce855659875a5c9f) |
---|---|
1/* 2 * Code for working with individual keys, and sorted sets of keys with in a 3 * btree node 4 * 5 * Copyright 2012 Google, Inc. 6 */ 7 8#include "bcache.h" 9#include "btree.h" | 1/* 2 * Code for working with individual keys, and sorted sets of keys with in a 3 * btree node 4 * 5 * Copyright 2012 Google, Inc. 6 */ 7 8#include "bcache.h" 9#include "btree.h" |
10#include "debug.h" | |
11 | 10 |
11#include <linux/console.h> |
|
12#include <linux/random.h> 13#include <linux/prefetch.h> 14 | 12#include <linux/random.h> 13#include <linux/prefetch.h> 14 |
15#ifdef CONFIG_BCACHE_DEBUG 16 17void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned set) 18{ 19 struct bkey *k, *next; 20 21 for (k = i->start; k < bset_bkey_last(i); k = next) { 22 next = bkey_next(k); 23 24 printk(KERN_ERR "block %u key %zi/%u: ", set, 25 (uint64_t *) k - i->d, i->keys); 26 27 if (b->ops->key_dump) 28 b->ops->key_dump(b, k); 29 else 30 printk("%llu:%llu\n", KEY_INODE(k), KEY_OFFSET(k)); 31 32 if (next < bset_bkey_last(i) && 33 bkey_cmp(k, b->ops->is_extents ? 34 &START_KEY(next) : next) > 0) 35 printk(KERN_ERR "Key skipped backwards\n"); 36 } 37} 38 39void bch_dump_bucket(struct btree_keys *b) 40{ 41 unsigned i; 42 43 console_lock(); 44 for (i = 0; i <= b->nsets; i++) 45 bch_dump_bset(b, b->set[i].data, 46 bset_sector_offset(b, b->set[i].data)); 47 console_unlock(); 48} 49 50int __bch_count_data(struct btree_keys *b) 51{ 52 unsigned ret = 0; 53 struct btree_iter iter; 54 struct bkey *k; 55 56 if (b->ops->is_extents) 57 for_each_key(b, k, &iter) 58 ret += KEY_SIZE(k); 59 return ret; 60} 61 62void __bch_check_keys(struct btree_keys *b, const char *fmt, ...) 63{ 64 va_list args; 65 struct bkey *k, *p = NULL; 66 struct btree_iter iter; 67 const char *err; 68 69 for_each_key(b, k, &iter) { 70 if (b->ops->is_extents) { 71 err = "Keys out of order"; 72 if (p && bkey_cmp(&START_KEY(p), &START_KEY(k)) > 0) 73 goto bug; 74 75 if (bch_ptr_invalid(b, k)) 76 continue; 77 78 err = "Overlapping keys"; 79 if (p && bkey_cmp(p, &START_KEY(k)) > 0) 80 goto bug; 81 } else { 82 if (bch_ptr_bad(b, k)) 83 continue; 84 85 err = "Duplicate keys"; 86 if (p && !bkey_cmp(p, k)) 87 goto bug; 88 } 89 p = k; 90 } 91#if 0 92 err = "Key larger than btree node key"; 93 if (p && bkey_cmp(p, &b->key) > 0) 94 goto bug; 95#endif 96 return; 97bug: 98 bch_dump_bucket(b); 99 100 va_start(args, fmt); 101 vprintk(fmt, args); 102 va_end(args); 103 104 panic("bch_check_keys error: %s:\n", err); 105} 106 107static void bch_btree_iter_next_check(struct btree_iter *iter) 108{ 109 struct bkey *k = iter->data->k, *next = bkey_next(k); 110 111 if (next < iter->data->end && 112 bkey_cmp(k, iter->b->ops->is_extents ? 113 &START_KEY(next) : next) > 0) { 114 bch_dump_bucket(iter->b); 115 panic("Key skipped backwards\n"); 116 } 117} 118 119#else 120 121static inline void bch_btree_iter_next_check(struct btree_iter *iter) {} 122 123#endif 124 |
|
15/* Keylists */ 16 17int __bch_keylist_realloc(struct keylist *l, unsigned u64s) 18{ 19 size_t oldsize = bch_keylist_nkeys(l); 20 size_t newsize = oldsize + u64s; 21 uint64_t *old_keys = l->keys_p == l->inline_keys ? NULL : l->keys_p; 22 uint64_t *new_keys; --- 1017 unchanged lines hidden (view full) --- 1040 bch_time_stats_update(&state->time, start_time); 1041} 1042 1043void bch_btree_sort_partial(struct btree *b, unsigned start, 1044 struct bset_sort_state *state) 1045{ 1046 size_t order = b->keys.page_order, keys = 0; 1047 struct btree_iter iter; | 125/* Keylists */ 126 127int __bch_keylist_realloc(struct keylist *l, unsigned u64s) 128{ 129 size_t oldsize = bch_keylist_nkeys(l); 130 size_t newsize = oldsize + u64s; 131 uint64_t *old_keys = l->keys_p == l->inline_keys ? NULL : l->keys_p; 132 uint64_t *new_keys; --- 1017 unchanged lines hidden (view full) --- 1150 bch_time_stats_update(&state->time, start_time); 1151} 1152 1153void bch_btree_sort_partial(struct btree *b, unsigned start, 1154 struct bset_sort_state *state) 1155{ 1156 size_t order = b->keys.page_order, keys = 0; 1157 struct btree_iter iter; |
1048 int oldsize = bch_count_data(b); | 1158 int oldsize = bch_count_data(&b->keys); |
1049 1050 __bch_btree_iter_init(&b->keys, &iter, NULL, &b->keys.set[start]); 1051 1052 if (start) { 1053 unsigned i; 1054 1055 for (i = start; i <= b->keys.nsets; i++) 1056 keys += b->keys.set[i].data->keys; 1057 1058 order = roundup_pow_of_two(__set_bytes(b->keys.set->data, 1059 keys)) / PAGE_SIZE; 1060 if (order) 1061 order = ilog2(order); 1062 } 1063 1064 __btree_sort(&b->keys, &iter, start, order, false, state); 1065 | 1159 1160 __bch_btree_iter_init(&b->keys, &iter, NULL, &b->keys.set[start]); 1161 1162 if (start) { 1163 unsigned i; 1164 1165 for (i = start; i <= b->keys.nsets; i++) 1166 keys += b->keys.set[i].data->keys; 1167 1168 order = roundup_pow_of_two(__set_bytes(b->keys.set->data, 1169 keys)) / PAGE_SIZE; 1170 if (order) 1171 order = ilog2(order); 1172 } 1173 1174 __btree_sort(&b->keys, &iter, start, order, false, state); 1175 |
1066 EBUG_ON(b->written && oldsize >= 0 && bch_count_data(b) != oldsize); | 1176 EBUG_ON(b->written && oldsize >= 0 && 1177 bch_count_data(&b->keys) != oldsize); |
1067} 1068EXPORT_SYMBOL(bch_btree_sort_partial); 1069 1070void bch_btree_sort_and_fix_extents(struct btree_keys *b, 1071 struct btree_iter *iter, 1072 struct bset_sort_state *state) 1073{ 1074 __btree_sort(b, iter, 0, b->page_order, true, state); --- 74 unchanged lines hidden --- | 1178} 1179EXPORT_SYMBOL(bch_btree_sort_partial); 1180 1181void bch_btree_sort_and_fix_extents(struct btree_keys *b, 1182 struct btree_iter *iter, 1183 struct bset_sort_state *state) 1184{ 1185 __btree_sort(b, iter, 0, b->page_order, true, state); --- 74 unchanged lines hidden --- |