diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-12-20 20:28:16 -0500 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-01-08 16:05:13 -0500 |
commit | a85e968e66a175c86d0410719ea84a5bd0f1d070 (patch) | |
tree | 83bd657e47b22862380db37af3051d81c1f4e74b /drivers/md | |
parent | 65d45231b56efb3db51eb441e2c68f8252ecdd12 (diff) |
bcache: Add struct btree_keys
Soon, bset.c won't need to depend on struct btree.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/bcache.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/bset.c | 179 | ||||
-rw-r--r-- | drivers/md/bcache/bset.h | 119 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 153 | ||||
-rw-r--r-- | drivers/md/bcache/btree.h | 93 | ||||
-rw-r--r-- | drivers/md/bcache/debug.c | 18 | ||||
-rw-r--r-- | drivers/md/bcache/extents.c | 19 | ||||
-rw-r--r-- | drivers/md/bcache/sysfs.c | 2 |
8 files changed, 322 insertions, 263 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 5c74d55cea7f..93b848419665 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h | |||
@@ -679,9 +679,9 @@ struct cache_set { | |||
679 | unsigned error_decay; | 679 | unsigned error_decay; |
680 | 680 | ||
681 | unsigned short journal_delay_ms; | 681 | unsigned short journal_delay_ms; |
682 | bool expensive_debug_checks; | ||
682 | unsigned verify:1; | 683 | unsigned verify:1; |
683 | unsigned key_merging_disabled:1; | 684 | unsigned key_merging_disabled:1; |
684 | unsigned expensive_debug_checks:1; | ||
685 | unsigned gc_always_rewrite:1; | 685 | unsigned gc_always_rewrite:1; |
686 | unsigned shrinker_disabled:1; | 686 | unsigned shrinker_disabled:1; |
687 | unsigned copy_gc_enabled:1; | 687 | unsigned copy_gc_enabled:1; |
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index c2c42cbbe885..f34ef56560ed 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
@@ -149,33 +149,33 @@ struct bkey_float { | |||
149 | #define BSET_CACHELINE 128 | 149 | #define BSET_CACHELINE 128 |
150 | 150 | ||
151 | /* Space required for the btree node keys */ | 151 | /* Space required for the btree node keys */ |
152 | static inline size_t btree_keys_bytes(struct btree *b) | 152 | static inline size_t btree_keys_bytes(struct btree_keys *b) |
153 | { | 153 | { |
154 | return PAGE_SIZE << b->page_order; | 154 | return PAGE_SIZE << b->page_order; |
155 | } | 155 | } |
156 | 156 | ||
157 | static inline size_t btree_keys_cachelines(struct btree *b) | 157 | static inline size_t btree_keys_cachelines(struct btree_keys *b) |
158 | { | 158 | { |
159 | return btree_keys_bytes(b) / BSET_CACHELINE; | 159 | return btree_keys_bytes(b) / BSET_CACHELINE; |
160 | } | 160 | } |
161 | 161 | ||
162 | /* Space required for the auxiliary search trees */ | 162 | /* Space required for the auxiliary search trees */ |
163 | static inline size_t bset_tree_bytes(struct btree *b) | 163 | static inline size_t bset_tree_bytes(struct btree_keys *b) |
164 | { | 164 | { |
165 | return btree_keys_cachelines(b) * sizeof(struct bkey_float); | 165 | return btree_keys_cachelines(b) * sizeof(struct bkey_float); |
166 | } | 166 | } |
167 | 167 | ||
168 | /* Space required for the prev pointers */ | 168 | /* Space required for the prev pointers */ |
169 | static inline size_t bset_prev_bytes(struct btree *b) | 169 | static inline size_t bset_prev_bytes(struct btree_keys *b) |
170 | { | 170 | { |
171 | return btree_keys_cachelines(b) * sizeof(uint8_t); | 171 | return btree_keys_cachelines(b) * sizeof(uint8_t); |
172 | } | 172 | } |
173 | 173 | ||
174 | /* Memory allocation */ | 174 | /* Memory allocation */ |
175 | 175 | ||
176 | void bch_btree_keys_free(struct btree *b) | 176 | void bch_btree_keys_free(struct btree_keys *b) |
177 | { | 177 | { |
178 | struct bset_tree *t = b->sets; | 178 | struct bset_tree *t = b->set; |
179 | 179 | ||
180 | if (bset_prev_bytes(b) < PAGE_SIZE) | 180 | if (bset_prev_bytes(b) < PAGE_SIZE) |
181 | kfree(t->prev); | 181 | kfree(t->prev); |
@@ -195,10 +195,11 @@ void bch_btree_keys_free(struct btree *b) | |||
195 | t->tree = NULL; | 195 | t->tree = NULL; |
196 | t->data = NULL; | 196 | t->data = NULL; |
197 | } | 197 | } |
198 | EXPORT_SYMBOL(bch_btree_keys_free); | ||
198 | 199 | ||
199 | int bch_btree_keys_alloc(struct btree *b, unsigned page_order, gfp_t gfp) | 200 | int bch_btree_keys_alloc(struct btree_keys *b, unsigned page_order, gfp_t gfp) |
200 | { | 201 | { |
201 | struct bset_tree *t = b->sets; | 202 | struct bset_tree *t = b->set; |
202 | 203 | ||
203 | BUG_ON(t->data); | 204 | BUG_ON(t->data); |
204 | 205 | ||
@@ -225,6 +226,29 @@ err: | |||
225 | bch_btree_keys_free(b); | 226 | bch_btree_keys_free(b); |
226 | return -ENOMEM; | 227 | return -ENOMEM; |
227 | } | 228 | } |
229 | EXPORT_SYMBOL(bch_btree_keys_alloc); | ||
230 | |||
231 | void bch_btree_keys_init(struct btree_keys *b, const struct btree_keys_ops *ops, | ||
232 | bool *expensive_debug_checks) | ||
233 | { | ||
234 | unsigned i; | ||
235 | |||
236 | b->ops = ops; | ||
237 | b->expensive_debug_checks = expensive_debug_checks; | ||
238 | b->nsets = 0; | ||
239 | b->last_set_unwritten = 0; | ||
240 | |||
241 | /* XXX: shouldn't be needed */ | ||
242 | for (i = 0; i < MAX_BSETS; i++) | ||
243 | b->set[i].size = 0; | ||
244 | /* | ||
245 | * Second loop starts at 1 because b->keys[0]->data is the memory we | ||
246 | * allocated | ||
247 | */ | ||
248 | for (i = 1; i < MAX_BSETS; i++) | ||
249 | b->set[i].data = NULL; | ||
250 | } | ||
251 | EXPORT_SYMBOL(bch_btree_keys_init); | ||
228 | 252 | ||
229 | /* Binary tree stuff for auxiliary search trees */ | 253 | /* Binary tree stuff for auxiliary search trees */ |
230 | 254 | ||
@@ -448,9 +472,9 @@ static void make_bfloat(struct bset_tree *t, unsigned j) | |||
448 | f->exponent = 127; | 472 | f->exponent = 127; |
449 | } | 473 | } |
450 | 474 | ||
451 | static void bset_alloc_tree(struct btree *b, struct bset_tree *t) | 475 | static void bset_alloc_tree(struct btree_keys *b, struct bset_tree *t) |
452 | { | 476 | { |
453 | if (t != b->sets) { | 477 | if (t != b->set) { |
454 | unsigned j = roundup(t[-1].size, | 478 | unsigned j = roundup(t[-1].size, |
455 | 64 / sizeof(struct bkey_float)); | 479 | 64 / sizeof(struct bkey_float)); |
456 | 480 | ||
@@ -458,27 +482,30 @@ static void bset_alloc_tree(struct btree *b, struct bset_tree *t) | |||
458 | t->prev = t[-1].prev + j; | 482 | t->prev = t[-1].prev + j; |
459 | } | 483 | } |
460 | 484 | ||
461 | while (t < b->sets + MAX_BSETS) | 485 | while (t < b->set + MAX_BSETS) |
462 | t++->size = 0; | 486 | t++->size = 0; |
463 | } | 487 | } |
464 | 488 | ||
465 | static void bch_bset_build_unwritten_tree(struct btree *b) | 489 | static void bch_bset_build_unwritten_tree(struct btree_keys *b) |
466 | { | 490 | { |
467 | struct bset_tree *t = bset_tree_last(b); | 491 | struct bset_tree *t = bset_tree_last(b); |
468 | 492 | ||
493 | BUG_ON(b->last_set_unwritten); | ||
494 | b->last_set_unwritten = 1; | ||
495 | |||
469 | bset_alloc_tree(b, t); | 496 | bset_alloc_tree(b, t); |
470 | 497 | ||
471 | if (t->tree != b->sets->tree + btree_keys_cachelines(b)) { | 498 | if (t->tree != b->set->tree + btree_keys_cachelines(b)) { |
472 | t->prev[0] = bkey_to_cacheline_offset(t->data->start); | 499 | t->prev[0] = bkey_to_cacheline_offset(t->data->start); |
473 | t->size = 1; | 500 | t->size = 1; |
474 | } | 501 | } |
475 | } | 502 | } |
476 | 503 | ||
477 | void bch_bset_init_next(struct btree *b, struct bset *i, uint64_t magic) | 504 | void bch_bset_init_next(struct btree_keys *b, struct bset *i, uint64_t magic) |
478 | { | 505 | { |
479 | if (i != b->sets->data) { | 506 | if (i != b->set->data) { |
480 | b->sets[++b->nsets].data = i; | 507 | b->set[++b->nsets].data = i; |
481 | i->seq = b->sets->data->seq; | 508 | i->seq = b->set->data->seq; |
482 | } else | 509 | } else |
483 | get_random_bytes(&i->seq, sizeof(uint64_t)); | 510 | get_random_bytes(&i->seq, sizeof(uint64_t)); |
484 | 511 | ||
@@ -488,18 +515,21 @@ void bch_bset_init_next(struct btree *b, struct bset *i, uint64_t magic) | |||
488 | 515 | ||
489 | bch_bset_build_unwritten_tree(b); | 516 | bch_bset_build_unwritten_tree(b); |
490 | } | 517 | } |
518 | EXPORT_SYMBOL(bch_bset_init_next); | ||
491 | 519 | ||
492 | static void bset_build_written_tree(struct btree *b) | 520 | void bch_bset_build_written_tree(struct btree_keys *b) |
493 | { | 521 | { |
494 | struct bset_tree *t = bset_tree_last(b); | 522 | struct bset_tree *t = bset_tree_last(b); |
495 | struct bkey *k = t->data->start; | 523 | struct bkey *k = t->data->start; |
496 | unsigned j, cacheline = 1; | 524 | unsigned j, cacheline = 1; |
497 | 525 | ||
526 | b->last_set_unwritten = 0; | ||
527 | |||
498 | bset_alloc_tree(b, t); | 528 | bset_alloc_tree(b, t); |
499 | 529 | ||
500 | t->size = min_t(unsigned, | 530 | t->size = min_t(unsigned, |
501 | bkey_to_cacheline(t, bset_bkey_last(t->data)), | 531 | bkey_to_cacheline(t, bset_bkey_last(t->data)), |
502 | b->sets->tree + btree_keys_cachelines(b) - t->tree); | 532 | b->set->tree + btree_keys_cachelines(b) - t->tree); |
503 | 533 | ||
504 | if (t->size < 2) { | 534 | if (t->size < 2) { |
505 | t->size = 0; | 535 | t->size = 0; |
@@ -532,13 +562,14 @@ static void bset_build_written_tree(struct btree *b) | |||
532 | j = inorder_next(j, t->size)) | 562 | j = inorder_next(j, t->size)) |
533 | make_bfloat(t, j); | 563 | make_bfloat(t, j); |
534 | } | 564 | } |
565 | EXPORT_SYMBOL(bch_bset_build_written_tree); | ||
535 | 566 | ||
536 | void bch_bset_fix_invalidated_key(struct btree *b, struct bkey *k) | 567 | void bch_bset_fix_invalidated_key(struct btree_keys *b, struct bkey *k) |
537 | { | 568 | { |
538 | struct bset_tree *t; | 569 | struct bset_tree *t; |
539 | unsigned inorder, j = 1; | 570 | unsigned inorder, j = 1; |
540 | 571 | ||
541 | for (t = b->sets; t <= bset_tree_last(b); t++) | 572 | for (t = b->set; t <= bset_tree_last(b); t++) |
542 | if (k < bset_bkey_last(t->data)) | 573 | if (k < bset_bkey_last(t->data)) |
543 | goto found_set; | 574 | goto found_set; |
544 | 575 | ||
@@ -577,8 +608,9 @@ fix_right: do { | |||
577 | j = j * 2 + 1; | 608 | j = j * 2 + 1; |
578 | } while (j < t->size); | 609 | } while (j < t->size); |
579 | } | 610 | } |
611 | EXPORT_SYMBOL(bch_bset_fix_invalidated_key); | ||
580 | 612 | ||
581 | static void bch_bset_fix_lookup_table(struct btree *b, | 613 | static void bch_bset_fix_lookup_table(struct btree_keys *b, |
582 | struct bset_tree *t, | 614 | struct bset_tree *t, |
583 | struct bkey *k) | 615 | struct bkey *k) |
584 | { | 616 | { |
@@ -613,7 +645,7 @@ static void bch_bset_fix_lookup_table(struct btree *b, | |||
613 | } | 645 | } |
614 | } | 646 | } |
615 | 647 | ||
616 | if (t->size == b->sets->tree + btree_keys_cachelines(b) - t->tree) | 648 | if (t->size == b->set->tree + btree_keys_cachelines(b) - t->tree) |
617 | return; | 649 | return; |
618 | 650 | ||
619 | /* Possibly add a new entry to the end of the lookup table */ | 651 | /* Possibly add a new entry to the end of the lookup table */ |
@@ -627,12 +659,12 @@ static void bch_bset_fix_lookup_table(struct btree *b, | |||
627 | } | 659 | } |
628 | } | 660 | } |
629 | 661 | ||
630 | void bch_bset_insert(struct btree *b, struct bkey *where, | 662 | void bch_bset_insert(struct btree_keys *b, struct bkey *where, |
631 | struct bkey *insert) | 663 | struct bkey *insert) |
632 | { | 664 | { |
633 | struct bset_tree *t = bset_tree_last(b); | 665 | struct bset_tree *t = bset_tree_last(b); |
634 | 666 | ||
635 | BUG_ON(t->data != write_block(b)); | 667 | BUG_ON(!b->last_set_unwritten); |
636 | BUG_ON(bset_byte_offset(b, t->data) + | 668 | BUG_ON(bset_byte_offset(b, t->data) + |
637 | __set_bytes(t->data, t->data->keys + bkey_u64s(insert)) > | 669 | __set_bytes(t->data, t->data->keys + bkey_u64s(insert)) > |
638 | PAGE_SIZE << b->page_order); | 670 | PAGE_SIZE << b->page_order); |
@@ -645,20 +677,17 @@ void bch_bset_insert(struct btree *b, struct bkey *where, | |||
645 | bkey_copy(where, insert); | 677 | bkey_copy(where, insert); |
646 | bch_bset_fix_lookup_table(b, t, where); | 678 | bch_bset_fix_lookup_table(b, t, where); |
647 | } | 679 | } |
680 | EXPORT_SYMBOL(bch_bset_insert); | ||
648 | 681 | ||
649 | struct bset_search_iter { | 682 | struct bset_search_iter { |
650 | struct bkey *l, *r; | 683 | struct bkey *l, *r; |
651 | }; | 684 | }; |
652 | 685 | ||
653 | static struct bset_search_iter bset_search_write_set(struct btree *b, | 686 | static struct bset_search_iter bset_search_write_set(struct bset_tree *t, |
654 | struct bset_tree *t, | ||
655 | const struct bkey *search) | 687 | const struct bkey *search) |
656 | { | 688 | { |
657 | unsigned li = 0, ri = t->size; | 689 | unsigned li = 0, ri = t->size; |
658 | 690 | ||
659 | BUG_ON(!b->nsets && | ||
660 | t->size < bkey_to_cacheline(t, bset_bkey_last(t->data))); | ||
661 | |||
662 | while (li + 1 != ri) { | 691 | while (li + 1 != ri) { |
663 | unsigned m = (li + ri) >> 1; | 692 | unsigned m = (li + ri) >> 1; |
664 | 693 | ||
@@ -674,8 +703,7 @@ static struct bset_search_iter bset_search_write_set(struct btree *b, | |||
674 | }; | 703 | }; |
675 | } | 704 | } |
676 | 705 | ||
677 | static struct bset_search_iter bset_search_tree(struct btree *b, | 706 | static struct bset_search_iter bset_search_tree(struct bset_tree *t, |
678 | struct bset_tree *t, | ||
679 | const struct bkey *search) | 707 | const struct bkey *search) |
680 | { | 708 | { |
681 | struct bkey *l, *r; | 709 | struct bkey *l, *r; |
@@ -759,7 +787,7 @@ struct bkey *__bch_bset_search(struct btree *b, struct bset_tree *t, | |||
759 | if (unlikely(!t->size)) { | 787 | if (unlikely(!t->size)) { |
760 | i.l = t->data->start; | 788 | i.l = t->data->start; |
761 | i.r = bset_bkey_last(t->data); | 789 | i.r = bset_bkey_last(t->data); |
762 | } else if (bset_written(b, t)) { | 790 | } else if (bset_written(&b->keys, t)) { |
763 | /* | 791 | /* |
764 | * Each node in the auxiliary search tree covers a certain range | 792 | * Each node in the auxiliary search tree covers a certain range |
765 | * of bits, and keys above and below the set it covers might | 793 | * of bits, and keys above and below the set it covers might |
@@ -773,12 +801,16 @@ struct bkey *__bch_bset_search(struct btree *b, struct bset_tree *t, | |||
773 | if (unlikely(bkey_cmp(search, t->data->start) < 0)) | 801 | if (unlikely(bkey_cmp(search, t->data->start) < 0)) |
774 | return t->data->start; | 802 | return t->data->start; |
775 | 803 | ||
776 | i = bset_search_tree(b, t, search); | 804 | i = bset_search_tree(t, search); |
777 | } else | 805 | } else { |
778 | i = bset_search_write_set(b, t, search); | 806 | BUG_ON(!b->keys.nsets && |
807 | t->size < bkey_to_cacheline(t, bset_bkey_last(t->data))); | ||
808 | |||
809 | i = bset_search_write_set(t, search); | ||
810 | } | ||
779 | 811 | ||
780 | if (expensive_debug_checks(b->c)) { | 812 | if (expensive_debug_checks(b->c)) { |
781 | BUG_ON(bset_written(b, t) && | 813 | BUG_ON(bset_written(&b->keys, t) && |
782 | i.l != t->data->start && | 814 | i.l != t->data->start && |
783 | bkey_cmp(tree_to_prev_bkey(t, | 815 | bkey_cmp(tree_to_prev_bkey(t, |
784 | inorder_to_tree(bkey_to_cacheline(t, i.l), t)), | 816 | inorder_to_tree(bkey_to_cacheline(t, i.l), t)), |
@@ -794,6 +826,7 @@ struct bkey *__bch_bset_search(struct btree *b, struct bset_tree *t, | |||
794 | 826 | ||
795 | return i.l; | 827 | return i.l; |
796 | } | 828 | } |
829 | EXPORT_SYMBOL(__bch_bset_search); | ||
797 | 830 | ||
798 | /* Btree iterator */ | 831 | /* Btree iterator */ |
799 | 832 | ||
@@ -833,7 +866,7 @@ static struct bkey *__bch_btree_iter_init(struct btree *b, | |||
833 | iter->b = b; | 866 | iter->b = b; |
834 | #endif | 867 | #endif |
835 | 868 | ||
836 | for (; start <= &b->sets[b->nsets]; start++) { | 869 | for (; start <= bset_tree_last(&b->keys); start++) { |
837 | ret = bch_bset_search(b, start, search); | 870 | ret = bch_bset_search(b, start, search); |
838 | bch_btree_iter_push(iter, ret, bset_bkey_last(start->data)); | 871 | bch_btree_iter_push(iter, ret, bset_bkey_last(start->data)); |
839 | } | 872 | } |
@@ -845,8 +878,9 @@ struct bkey *bch_btree_iter_init(struct btree *b, | |||
845 | struct btree_iter *iter, | 878 | struct btree_iter *iter, |
846 | struct bkey *search) | 879 | struct bkey *search) |
847 | { | 880 | { |
848 | return __bch_btree_iter_init(b, iter, search, b->sets); | 881 | return __bch_btree_iter_init(b, iter, search, b->keys.set); |
849 | } | 882 | } |
883 | EXPORT_SYMBOL(bch_btree_iter_init); | ||
850 | 884 | ||
851 | static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, | 885 | static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, |
852 | btree_iter_cmp_fn *cmp) | 886 | btree_iter_cmp_fn *cmp) |
@@ -879,9 +913,10 @@ struct bkey *bch_btree_iter_next(struct btree_iter *iter) | |||
879 | return __bch_btree_iter_next(iter, btree_iter_cmp); | 913 | return __bch_btree_iter_next(iter, btree_iter_cmp); |
880 | 914 | ||
881 | } | 915 | } |
916 | EXPORT_SYMBOL(bch_btree_iter_next); | ||
882 | 917 | ||
883 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter, | 918 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter, |
884 | struct btree *b, ptr_filter_fn fn) | 919 | struct btree_keys *b, ptr_filter_fn fn) |
885 | { | 920 | { |
886 | struct bkey *ret; | 921 | struct bkey *ret; |
887 | 922 | ||
@@ -913,15 +948,16 @@ int bch_bset_sort_state_init(struct bset_sort_state *state, unsigned page_order) | |||
913 | 948 | ||
914 | return 0; | 949 | return 0; |
915 | } | 950 | } |
951 | EXPORT_SYMBOL(bch_bset_sort_state_init); | ||
916 | 952 | ||
917 | static void btree_mergesort(struct btree *b, struct bset *out, | 953 | static void btree_mergesort(struct btree_keys *b, struct bset *out, |
918 | struct btree_iter *iter, | 954 | struct btree_iter *iter, |
919 | bool fixup, bool remove_stale) | 955 | bool fixup, bool remove_stale) |
920 | { | 956 | { |
921 | int i; | 957 | int i; |
922 | struct bkey *k, *last = NULL; | 958 | struct bkey *k, *last = NULL; |
923 | BKEY_PADDED(k) tmp; | 959 | BKEY_PADDED(k) tmp; |
924 | bool (*bad)(struct btree *, const struct bkey *) = remove_stale | 960 | bool (*bad)(struct btree_keys *, const struct bkey *) = remove_stale |
925 | ? bch_ptr_bad | 961 | ? bch_ptr_bad |
926 | : bch_ptr_invalid; | 962 | : bch_ptr_invalid; |
927 | 963 | ||
@@ -955,7 +991,7 @@ static void btree_mergesort(struct btree *b, struct bset *out, | |||
955 | pr_debug("sorted %i keys", out->keys); | 991 | pr_debug("sorted %i keys", out->keys); |
956 | } | 992 | } |
957 | 993 | ||
958 | static void __btree_sort(struct btree *b, struct btree_iter *iter, | 994 | static void __btree_sort(struct btree_keys *b, struct btree_iter *iter, |
959 | unsigned start, unsigned order, bool fixup, | 995 | unsigned start, unsigned order, bool fixup, |
960 | struct bset_sort_state *state) | 996 | struct bset_sort_state *state) |
961 | { | 997 | { |
@@ -968,7 +1004,7 @@ static void __btree_sort(struct btree *b, struct btree_iter *iter, | |||
968 | 1004 | ||
969 | out = page_address(mempool_alloc(state->pool, GFP_NOIO)); | 1005 | out = page_address(mempool_alloc(state->pool, GFP_NOIO)); |
970 | used_mempool = true; | 1006 | used_mempool = true; |
971 | order = ilog2(bucket_pages(b->c)); | 1007 | order = state->page_order; |
972 | } | 1008 | } |
973 | 1009 | ||
974 | start_time = local_clock(); | 1010 | start_time = local_clock(); |
@@ -983,13 +1019,13 @@ static void __btree_sort(struct btree *b, struct btree_iter *iter, | |||
983 | * memcpy() | 1019 | * memcpy() |
984 | */ | 1020 | */ |
985 | 1021 | ||
986 | out->magic = bset_magic(&b->c->sb); | 1022 | out->magic = b->set->data->magic; |
987 | out->seq = b->sets[0].data->seq; | 1023 | out->seq = b->set->data->seq; |
988 | out->version = b->sets[0].data->version; | 1024 | out->version = b->set->data->version; |
989 | swap(out, b->sets[0].data); | 1025 | swap(out, b->set->data); |
990 | } else { | 1026 | } else { |
991 | b->sets[start].data->keys = out->keys; | 1027 | b->set[start].data->keys = out->keys; |
992 | memcpy(b->sets[start].data->start, out->start, | 1028 | memcpy(b->set[start].data->start, out->start, |
993 | (void *) bset_bkey_last(out) - (void *) out->start); | 1029 | (void *) bset_bkey_last(out) - (void *) out->start); |
994 | } | 1030 | } |
995 | 1031 | ||
@@ -998,7 +1034,7 @@ static void __btree_sort(struct btree *b, struct btree_iter *iter, | |||
998 | else | 1034 | else |
999 | free_pages((unsigned long) out, order); | 1035 | free_pages((unsigned long) out, order); |
1000 | 1036 | ||
1001 | bset_build_written_tree(b); | 1037 | bch_bset_build_written_tree(b); |
1002 | 1038 | ||
1003 | if (!start) | 1039 | if (!start) |
1004 | bch_time_stats_update(&state->time, start_time); | 1040 | bch_time_stats_update(&state->time, start_time); |
@@ -1007,34 +1043,32 @@ static void __btree_sort(struct btree *b, struct btree_iter *iter, | |||
1007 | void bch_btree_sort_partial(struct btree *b, unsigned start, | 1043 | void bch_btree_sort_partial(struct btree *b, unsigned start, |
1008 | struct bset_sort_state *state) | 1044 | struct bset_sort_state *state) |
1009 | { | 1045 | { |
1010 | size_t order = b->page_order, keys = 0; | 1046 | size_t order = b->keys.page_order, keys = 0; |
1011 | struct btree_iter iter; | 1047 | struct btree_iter iter; |
1012 | int oldsize = bch_count_data(b); | 1048 | int oldsize = bch_count_data(b); |
1013 | 1049 | ||
1014 | __bch_btree_iter_init(b, &iter, NULL, &b->sets[start]); | 1050 | __bch_btree_iter_init(b, &iter, NULL, &b->keys.set[start]); |
1015 | |||
1016 | BUG_ON(!bset_written(b, bset_tree_last(b)) && | ||
1017 | (bset_tree_last(b)->size || b->nsets)); | ||
1018 | 1051 | ||
1019 | if (start) { | 1052 | if (start) { |
1020 | unsigned i; | 1053 | unsigned i; |
1021 | 1054 | ||
1022 | for (i = start; i <= b->nsets; i++) | 1055 | for (i = start; i <= b->keys.nsets; i++) |
1023 | keys += b->sets[i].data->keys; | 1056 | keys += b->keys.set[i].data->keys; |
1024 | 1057 | ||
1025 | order = roundup_pow_of_two(__set_bytes(b->sets->data, | 1058 | order = roundup_pow_of_two(__set_bytes(b->keys.set->data, |
1026 | keys)) / PAGE_SIZE; | 1059 | keys)) / PAGE_SIZE; |
1027 | if (order) | 1060 | if (order) |
1028 | order = ilog2(order); | 1061 | order = ilog2(order); |
1029 | } | 1062 | } |
1030 | 1063 | ||
1031 | __btree_sort(b, &iter, start, order, false, state); | 1064 | __btree_sort(&b->keys, &iter, start, order, false, state); |
1032 | 1065 | ||
1033 | EBUG_ON(b->written && oldsize >= 0 && bch_count_data(b) != oldsize); | 1066 | EBUG_ON(b->written && oldsize >= 0 && bch_count_data(b) != oldsize); |
1034 | } | 1067 | } |
1035 | EXPORT_SYMBOL(bch_btree_sort_partial); | 1068 | EXPORT_SYMBOL(bch_btree_sort_partial); |
1036 | 1069 | ||
1037 | void bch_btree_sort_and_fix_extents(struct btree *b, struct btree_iter *iter, | 1070 | void bch_btree_sort_and_fix_extents(struct btree_keys *b, |
1071 | struct btree_iter *iter, | ||
1038 | struct bset_sort_state *state) | 1072 | struct bset_sort_state *state) |
1039 | { | 1073 | { |
1040 | __btree_sort(b, iter, 0, b->page_order, true, state); | 1074 | __btree_sort(b, iter, 0, b->page_order, true, state); |
@@ -1048,11 +1082,11 @@ void bch_btree_sort_into(struct btree *b, struct btree *new, | |||
1048 | struct btree_iter iter; | 1082 | struct btree_iter iter; |
1049 | bch_btree_iter_init(b, &iter, NULL); | 1083 | bch_btree_iter_init(b, &iter, NULL); |
1050 | 1084 | ||
1051 | btree_mergesort(b, new->sets->data, &iter, false, true); | 1085 | btree_mergesort(&b->keys, new->keys.set->data, &iter, false, true); |
1052 | 1086 | ||
1053 | bch_time_stats_update(&state->time, start_time); | 1087 | bch_time_stats_update(&state->time, start_time); |
1054 | 1088 | ||
1055 | new->sets->size = 0; | 1089 | new->keys.set->size = 0; // XXX: why? |
1056 | } | 1090 | } |
1057 | 1091 | ||
1058 | #define SORT_CRIT (4096 / sizeof(uint64_t)) | 1092 | #define SORT_CRIT (4096 / sizeof(uint64_t)) |
@@ -1062,28 +1096,31 @@ void bch_btree_sort_lazy(struct btree *b, struct bset_sort_state *state) | |||
1062 | unsigned crit = SORT_CRIT; | 1096 | unsigned crit = SORT_CRIT; |
1063 | int i; | 1097 | int i; |
1064 | 1098 | ||
1099 | b->keys.last_set_unwritten = 0; | ||
1100 | |||
1065 | /* Don't sort if nothing to do */ | 1101 | /* Don't sort if nothing to do */ |
1066 | if (!b->nsets) | 1102 | if (!b->keys.nsets) |
1067 | goto out; | 1103 | goto out; |
1068 | 1104 | ||
1069 | for (i = b->nsets - 1; i >= 0; --i) { | 1105 | for (i = b->keys.nsets - 1; i >= 0; --i) { |
1070 | crit *= state->crit_factor; | 1106 | crit *= state->crit_factor; |
1071 | 1107 | ||
1072 | if (b->sets[i].data->keys < crit) { | 1108 | if (b->keys.set[i].data->keys < crit) { |
1073 | bch_btree_sort_partial(b, i, state); | 1109 | bch_btree_sort_partial(b, i, state); |
1074 | return; | 1110 | return; |
1075 | } | 1111 | } |
1076 | } | 1112 | } |
1077 | 1113 | ||
1078 | /* Sort if we'd overflow */ | 1114 | /* Sort if we'd overflow */ |
1079 | if (b->nsets + 1 == MAX_BSETS) { | 1115 | if (b->keys.nsets + 1 == MAX_BSETS) { |
1080 | bch_btree_sort(b, state); | 1116 | bch_btree_sort(b, state); |
1081 | return; | 1117 | return; |
1082 | } | 1118 | } |
1083 | 1119 | ||
1084 | out: | 1120 | out: |
1085 | bset_build_written_tree(b); | 1121 | bch_bset_build_written_tree(&b->keys); |
1086 | } | 1122 | } |
1123 | EXPORT_SYMBOL(bch_btree_sort_lazy); | ||
1087 | 1124 | ||
1088 | /* Sysfs stuff */ | 1125 | /* Sysfs stuff */ |
1089 | 1126 | ||
@@ -1102,12 +1139,12 @@ static int btree_bset_stats(struct btree_op *op, struct btree *b) | |||
1102 | 1139 | ||
1103 | stats->nodes++; | 1140 | stats->nodes++; |
1104 | 1141 | ||
1105 | for (i = 0; i <= b->nsets; i++) { | 1142 | for (i = 0; i <= b->keys.nsets; i++) { |
1106 | struct bset_tree *t = &b->sets[i]; | 1143 | struct bset_tree *t = &b->keys.set[i]; |
1107 | size_t bytes = t->data->keys * sizeof(uint64_t); | 1144 | size_t bytes = t->data->keys * sizeof(uint64_t); |
1108 | size_t j; | 1145 | size_t j; |
1109 | 1146 | ||
1110 | if (bset_written(b, t)) { | 1147 | if (bset_written(&b->keys, t)) { |
1111 | stats->sets_written++; | 1148 | stats->sets_written++; |
1112 | stats->bytes_written += bytes; | 1149 | stats->bytes_written += bytes; |
1113 | 1150 | ||
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h index b5797129e919..87da828477f3 100644 --- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h | |||
@@ -145,6 +145,9 @@ | |||
145 | */ | 145 | */ |
146 | 146 | ||
147 | struct btree; | 147 | struct btree; |
148 | struct btree_keys; | ||
149 | struct btree_iter; | ||
150 | struct btree_iter_set; | ||
148 | struct bkey_float; | 151 | struct bkey_float; |
149 | 152 | ||
150 | #define MAX_BSETS 4U | 153 | #define MAX_BSETS 4U |
@@ -181,6 +184,74 @@ struct bset_tree { | |||
181 | struct bset *data; | 184 | struct bset *data; |
182 | }; | 185 | }; |
183 | 186 | ||
187 | struct btree_keys_ops { | ||
188 | bool (*sort_cmp)(struct btree_iter_set, | ||
189 | struct btree_iter_set); | ||
190 | struct bkey *(*sort_fixup)(struct btree_iter *, struct bkey *); | ||
191 | bool (*key_invalid)(struct btree_keys *, | ||
192 | const struct bkey *); | ||
193 | bool (*key_bad)(struct btree_keys *, const struct bkey *); | ||
194 | bool (*key_merge)(struct btree_keys *, | ||
195 | struct bkey *, struct bkey *); | ||
196 | |||
197 | /* | ||
198 | * Only used for deciding whether to use START_KEY(k) or just the key | ||
199 | * itself in a couple places | ||
200 | */ | ||
201 | bool is_extents; | ||
202 | }; | ||
203 | |||
204 | struct btree_keys { | ||
205 | const struct btree_keys_ops *ops; | ||
206 | uint8_t page_order; | ||
207 | uint8_t nsets; | ||
208 | unsigned last_set_unwritten:1; | ||
209 | bool *expensive_debug_checks; | ||
210 | |||
211 | /* | ||
212 | * Sets of sorted keys - the real btree node - plus a binary search tree | ||
213 | * | ||
214 | * set[0] is special; set[0]->tree, set[0]->prev and set[0]->data point | ||
215 | * to the memory we have allocated for this btree node. Additionally, | ||
216 | * set[0]->data points to the entire btree node as it exists on disk. | ||
217 | */ | ||
218 | struct bset_tree set[MAX_BSETS]; | ||
219 | }; | ||
220 | |||
221 | static inline struct bset_tree *bset_tree_last(struct btree_keys *b) | ||
222 | { | ||
223 | return b->set + b->nsets; | ||
224 | } | ||
225 | |||
226 | static inline bool bset_written(struct btree_keys *b, struct bset_tree *t) | ||
227 | { | ||
228 | return t <= b->set + b->nsets - b->last_set_unwritten; | ||
229 | } | ||
230 | |||
231 | static inline bool bkey_written(struct btree_keys *b, struct bkey *k) | ||
232 | { | ||
233 | return !b->last_set_unwritten || k < b->set[b->nsets].data->start; | ||
234 | } | ||
235 | |||
236 | static inline unsigned bset_byte_offset(struct btree_keys *b, struct bset *i) | ||
237 | { | ||
238 | return ((size_t) i) - ((size_t) b->set->data); | ||
239 | } | ||
240 | |||
241 | static inline unsigned bset_sector_offset(struct btree_keys *b, struct bset *i) | ||
242 | { | ||
243 | return bset_byte_offset(b, i) >> 9; | ||
244 | } | ||
245 | |||
246 | static inline bool btree_keys_expensive_checks(struct btree_keys *b) | ||
247 | { | ||
248 | #ifdef CONFIG_BCACHE_DEBUG | ||
249 | return *b->expensive_debug_checks; | ||
250 | #else | ||
251 | return false; | ||
252 | #endif | ||
253 | } | ||
254 | |||
184 | #define __set_bytes(i, k) (sizeof(*(i)) + (k) * sizeof(uint64_t)) | 255 | #define __set_bytes(i, k) (sizeof(*(i)) + (k) * sizeof(uint64_t)) |
185 | #define set_bytes(i) __set_bytes(i, i->keys) | 256 | #define set_bytes(i) __set_bytes(i, i->keys) |
186 | 257 | ||
@@ -189,12 +260,34 @@ struct bset_tree { | |||
189 | #define set_blocks(i, block_bytes) \ | 260 | #define set_blocks(i, block_bytes) \ |
190 | __set_blocks(i, (i)->keys, block_bytes) | 261 | __set_blocks(i, (i)->keys, block_bytes) |
191 | 262 | ||
192 | void bch_btree_keys_free(struct btree *); | 263 | static inline struct bset *bset_next_set(struct btree_keys *b, |
193 | int bch_btree_keys_alloc(struct btree *, unsigned, gfp_t); | 264 | unsigned block_bytes) |
265 | { | ||
266 | struct bset *i = bset_tree_last(b)->data; | ||
267 | |||
268 | return ((void *) i) + roundup(set_bytes(i), block_bytes); | ||
269 | } | ||
270 | |||
271 | void bch_btree_keys_free(struct btree_keys *); | ||
272 | int bch_btree_keys_alloc(struct btree_keys *, unsigned, gfp_t); | ||
273 | void bch_btree_keys_init(struct btree_keys *, const struct btree_keys_ops *, | ||
274 | bool *); | ||
194 | 275 | ||
195 | void bch_bset_fix_invalidated_key(struct btree *, struct bkey *); | 276 | void bch_bset_init_next(struct btree_keys *, struct bset *, uint64_t); |
196 | void bch_bset_init_next(struct btree *, struct bset *, uint64_t); | 277 | void bch_bset_build_written_tree(struct btree_keys *); |
197 | void bch_bset_insert(struct btree *, struct bkey *, struct bkey *); | 278 | void bch_bset_fix_invalidated_key(struct btree_keys *, struct bkey *); |
279 | void bch_bset_insert(struct btree_keys *, struct bkey *, struct bkey *); | ||
280 | |||
281 | /* | ||
282 | * Tries to merge l and r: l should be lower than r | ||
283 | * Returns true if we were able to merge. If we did merge, l will be the merged | ||
284 | * key, r will be untouched. | ||
285 | */ | ||
286 | static inline bool bch_bkey_try_merge(struct btree_keys *b, | ||
287 | struct bkey *l, struct bkey *r) | ||
288 | { | ||
289 | return b->ops->key_merge ? b->ops->key_merge(b, l, r) : false; | ||
290 | } | ||
198 | 291 | ||
199 | /* Btree key iteration */ | 292 | /* Btree key iteration */ |
200 | 293 | ||
@@ -208,11 +301,11 @@ struct btree_iter { | |||
208 | } data[MAX_BSETS]; | 301 | } data[MAX_BSETS]; |
209 | }; | 302 | }; |
210 | 303 | ||
211 | typedef bool (*ptr_filter_fn)(struct btree *, const struct bkey *); | 304 | typedef bool (*ptr_filter_fn)(struct btree_keys *, const struct bkey *); |
212 | 305 | ||
213 | struct bkey *bch_btree_iter_next(struct btree_iter *); | 306 | struct bkey *bch_btree_iter_next(struct btree_iter *); |
214 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *, | 307 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *, |
215 | struct btree *, ptr_filter_fn); | 308 | struct btree_keys *, ptr_filter_fn); |
216 | 309 | ||
217 | void bch_btree_iter_push(struct btree_iter *, struct bkey *, struct bkey *); | 310 | void bch_btree_iter_push(struct btree_iter *, struct bkey *, struct bkey *); |
218 | struct bkey *bch_btree_iter_init(struct btree *, struct btree_iter *, | 311 | struct bkey *bch_btree_iter_init(struct btree *, struct btree_iter *, |
@@ -246,7 +339,7 @@ int bch_bset_sort_state_init(struct bset_sort_state *, unsigned); | |||
246 | void bch_btree_sort_lazy(struct btree *, struct bset_sort_state *); | 339 | void bch_btree_sort_lazy(struct btree *, struct bset_sort_state *); |
247 | void bch_btree_sort_into(struct btree *, struct btree *, | 340 | void bch_btree_sort_into(struct btree *, struct btree *, |
248 | struct bset_sort_state *); | 341 | struct bset_sort_state *); |
249 | void bch_btree_sort_and_fix_extents(struct btree *, struct btree_iter *, | 342 | void bch_btree_sort_and_fix_extents(struct btree_keys *, struct btree_iter *, |
250 | struct bset_sort_state *); | 343 | struct bset_sort_state *); |
251 | void bch_btree_sort_partial(struct btree *, unsigned, | 344 | void bch_btree_sort_partial(struct btree *, unsigned, |
252 | struct bset_sort_state *); | 345 | struct bset_sort_state *); |
@@ -311,6 +404,16 @@ static inline bool bch_cut_back(const struct bkey *where, struct bkey *k) | |||
311 | _ret; \ | 404 | _ret; \ |
312 | }) | 405 | }) |
313 | 406 | ||
407 | static inline bool bch_ptr_invalid(struct btree_keys *b, const struct bkey *k) | ||
408 | { | ||
409 | return b->ops->key_invalid(b, k); | ||
410 | } | ||
411 | |||
412 | static inline bool bch_ptr_bad(struct btree_keys *b, const struct bkey *k) | ||
413 | { | ||
414 | return b->ops->key_bad(b, k); | ||
415 | } | ||
416 | |||
314 | /* Keylists */ | 417 | /* Keylists */ |
315 | 418 | ||
316 | struct keylist { | 419 | struct keylist { |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 6734e2759b93..5d7dee8bb850 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -107,14 +107,6 @@ enum { | |||
107 | 107 | ||
108 | static struct workqueue_struct *btree_io_wq; | 108 | static struct workqueue_struct *btree_io_wq; |
109 | 109 | ||
110 | static inline bool should_split(struct btree *b) | ||
111 | { | ||
112 | struct bset *i = write_block(b); | ||
113 | return b->written >= btree_blocks(b) || | ||
114 | (b->written + __set_blocks(i, i->keys + 15, block_bytes(b->c)) | ||
115 | > btree_blocks(b)); | ||
116 | } | ||
117 | |||
118 | #define insert_lock(s, b) ((b)->level <= (s)->lock) | 110 | #define insert_lock(s, b) ((b)->level <= (s)->lock) |
119 | 111 | ||
120 | /* | 112 | /* |
@@ -182,6 +174,19 @@ static inline bool should_split(struct btree *b) | |||
182 | _r; \ | 174 | _r; \ |
183 | }) | 175 | }) |
184 | 176 | ||
177 | static inline struct bset *write_block(struct btree *b) | ||
178 | { | ||
179 | return ((void *) btree_bset_first(b)) + b->written * block_bytes(b->c); | ||
180 | } | ||
181 | |||
182 | static inline bool should_split(struct btree *b) | ||
183 | { | ||
184 | struct bset *i = write_block(b); | ||
185 | return b->written >= btree_blocks(b) || | ||
186 | (b->written + __set_blocks(i, i->keys + 15, block_bytes(b->c)) | ||
187 | > btree_blocks(b)); | ||
188 | } | ||
189 | |||
185 | /* Btree key manipulation */ | 190 | /* Btree key manipulation */ |
186 | 191 | ||
187 | void bkey_put(struct cache_set *c, struct bkey *k) | 192 | void bkey_put(struct cache_set *c, struct bkey *k) |
@@ -222,7 +227,7 @@ void bch_btree_node_read_done(struct btree *b) | |||
222 | goto err; | 227 | goto err; |
223 | 228 | ||
224 | for (; | 229 | for (; |
225 | b->written < btree_blocks(b) && i->seq == b->sets[0].data->seq; | 230 | b->written < btree_blocks(b) && i->seq == b->keys.set[0].data->seq; |
226 | i = write_block(b)) { | 231 | i = write_block(b)) { |
227 | err = "unsupported bset version"; | 232 | err = "unsupported bset version"; |
228 | if (i->version > BCACHE_BSET_VERSION) | 233 | if (i->version > BCACHE_BSET_VERSION) |
@@ -250,7 +255,7 @@ void bch_btree_node_read_done(struct btree *b) | |||
250 | } | 255 | } |
251 | 256 | ||
252 | err = "empty set"; | 257 | err = "empty set"; |
253 | if (i != b->sets[0].data && !i->keys) | 258 | if (i != b->keys.set[0].data && !i->keys) |
254 | goto err; | 259 | goto err; |
255 | 260 | ||
256 | bch_btree_iter_push(iter, i->start, bset_bkey_last(i)); | 261 | bch_btree_iter_push(iter, i->start, bset_bkey_last(i)); |
@@ -260,21 +265,22 @@ void bch_btree_node_read_done(struct btree *b) | |||
260 | 265 | ||
261 | err = "corrupted btree"; | 266 | err = "corrupted btree"; |
262 | for (i = write_block(b); | 267 | for (i = write_block(b); |
263 | bset_sector_offset(b, i) < KEY_SIZE(&b->key); | 268 | bset_sector_offset(&b->keys, i) < KEY_SIZE(&b->key); |
264 | i = ((void *) i) + block_bytes(b->c)) | 269 | i = ((void *) i) + block_bytes(b->c)) |
265 | if (i->seq == b->sets[0].data->seq) | 270 | if (i->seq == b->keys.set[0].data->seq) |
266 | goto err; | 271 | goto err; |
267 | 272 | ||
268 | bch_btree_sort_and_fix_extents(b, iter, &b->c->sort); | 273 | bch_btree_sort_and_fix_extents(&b->keys, iter, &b->c->sort); |
269 | 274 | ||
270 | i = b->sets[0].data; | 275 | i = b->keys.set[0].data; |
271 | err = "short btree key"; | 276 | err = "short btree key"; |
272 | if (b->sets[0].size && | 277 | if (b->keys.set[0].size && |
273 | bkey_cmp(&b->key, &b->sets[0].end) < 0) | 278 | bkey_cmp(&b->key, &b->keys.set[0].end) < 0) |
274 | goto err; | 279 | goto err; |
275 | 280 | ||
276 | if (b->written < btree_blocks(b)) | 281 | if (b->written < btree_blocks(b)) |
277 | bch_bset_init_next(b, write_block(b), bset_magic(&b->c->sb)); | 282 | bch_bset_init_next(&b->keys, write_block(b), |
283 | bset_magic(&b->c->sb)); | ||
278 | out: | 284 | out: |
279 | mempool_free(iter, b->c->fill_iter); | 285 | mempool_free(iter, b->c->fill_iter); |
280 | return; | 286 | return; |
@@ -308,7 +314,7 @@ static void bch_btree_node_read(struct btree *b) | |||
308 | bio->bi_end_io = btree_node_read_endio; | 314 | bio->bi_end_io = btree_node_read_endio; |
309 | bio->bi_private = &cl; | 315 | bio->bi_private = &cl; |
310 | 316 | ||
311 | bch_bio_map(bio, b->sets[0].data); | 317 | bch_bio_map(bio, b->keys.set[0].data); |
312 | 318 | ||
313 | bch_submit_bbio(bio, b->c, &b->key, 0); | 319 | bch_submit_bbio(bio, b->c, &b->key, 0); |
314 | closure_sync(&cl); | 320 | closure_sync(&cl); |
@@ -427,7 +433,7 @@ static void do_btree_node_write(struct btree *b) | |||
427 | 433 | ||
428 | bkey_copy(&k.key, &b->key); | 434 | bkey_copy(&k.key, &b->key); |
429 | SET_PTR_OFFSET(&k.key, 0, PTR_OFFSET(&k.key, 0) + | 435 | SET_PTR_OFFSET(&k.key, 0, PTR_OFFSET(&k.key, 0) + |
430 | bset_sector_offset(b, i)); | 436 | bset_sector_offset(&b->keys, i)); |
431 | 437 | ||
432 | if (!bio_alloc_pages(b->bio, GFP_NOIO)) { | 438 | if (!bio_alloc_pages(b->bio, GFP_NOIO)) { |
433 | int j; | 439 | int j; |
@@ -475,12 +481,13 @@ void bch_btree_node_write(struct btree *b, struct closure *parent) | |||
475 | 481 | ||
476 | do_btree_node_write(b); | 482 | do_btree_node_write(b); |
477 | 483 | ||
478 | b->written += set_blocks(i, block_bytes(b->c)); | ||
479 | atomic_long_add(set_blocks(i, block_bytes(b->c)) * b->c->sb.block_size, | 484 | atomic_long_add(set_blocks(i, block_bytes(b->c)) * b->c->sb.block_size, |
480 | &PTR_CACHE(b->c, &b->key, 0)->btree_sectors_written); | 485 | &PTR_CACHE(b->c, &b->key, 0)->btree_sectors_written); |
481 | 486 | ||
487 | b->written += set_blocks(i, block_bytes(b->c)); | ||
488 | |||
482 | /* If not a leaf node, always sort */ | 489 | /* If not a leaf node, always sort */ |
483 | if (b->level && b->nsets) | 490 | if (b->level && b->keys.nsets) |
484 | bch_btree_sort(b, &b->c->sort); | 491 | bch_btree_sort(b, &b->c->sort); |
485 | else | 492 | else |
486 | bch_btree_sort_lazy(b, &b->c->sort); | 493 | bch_btree_sort_lazy(b, &b->c->sort); |
@@ -489,11 +496,12 @@ void bch_btree_node_write(struct btree *b, struct closure *parent) | |||
489 | * do verify if there was more than one set initially (i.e. we did a | 496 | * do verify if there was more than one set initially (i.e. we did a |
490 | * sort) and we sorted down to a single set: | 497 | * sort) and we sorted down to a single set: |
491 | */ | 498 | */ |
492 | if (i != b->sets->data && !b->nsets) | 499 | if (i != b->keys.set->data && !b->keys.nsets) |
493 | bch_btree_verify(b); | 500 | bch_btree_verify(b); |
494 | 501 | ||
495 | if (b->written < btree_blocks(b)) | 502 | if (b->written < btree_blocks(b)) |
496 | bch_bset_init_next(b, write_block(b), bset_magic(&b->c->sb)); | 503 | bch_bset_init_next(&b->keys, write_block(b), |
504 | bset_magic(&b->c->sb)); | ||
497 | } | 505 | } |
498 | 506 | ||
499 | static void bch_btree_node_write_sync(struct btree *b) | 507 | static void bch_btree_node_write_sync(struct btree *b) |
@@ -553,24 +561,6 @@ static void bch_btree_leaf_dirty(struct btree *b, atomic_t *journal_ref) | |||
553 | * mca -> memory cache | 561 | * mca -> memory cache |
554 | */ | 562 | */ |
555 | 563 | ||
556 | static void mca_reinit(struct btree *b) | ||
557 | { | ||
558 | unsigned i; | ||
559 | |||
560 | b->flags = 0; | ||
561 | b->written = 0; | ||
562 | b->nsets = 0; | ||
563 | |||
564 | for (i = 0; i < MAX_BSETS; i++) | ||
565 | b->sets[i].size = 0; | ||
566 | /* | ||
567 | * Second loop starts at 1 because b->sets[0]->data is the memory we | ||
568 | * allocated | ||
569 | */ | ||
570 | for (i = 1; i < MAX_BSETS; i++) | ||
571 | b->sets[i].data = NULL; | ||
572 | } | ||
573 | |||
574 | #define mca_reserve(c) (((c->root && c->root->level) \ | 564 | #define mca_reserve(c) (((c->root && c->root->level) \ |
575 | ? c->root->level : 1) * 8 + 16) | 565 | ? c->root->level : 1) * 8 + 16) |
576 | #define mca_can_free(c) \ | 566 | #define mca_can_free(c) \ |
@@ -580,7 +570,7 @@ static void mca_data_free(struct btree *b) | |||
580 | { | 570 | { |
581 | BUG_ON(b->io_mutex.count != 1); | 571 | BUG_ON(b->io_mutex.count != 1); |
582 | 572 | ||
583 | bch_btree_keys_free(b); | 573 | bch_btree_keys_free(&b->keys); |
584 | 574 | ||
585 | b->c->bucket_cache_used--; | 575 | b->c->bucket_cache_used--; |
586 | list_move(&b->list, &b->c->btree_cache_freed); | 576 | list_move(&b->list, &b->c->btree_cache_freed); |
@@ -602,7 +592,7 @@ static unsigned btree_order(struct bkey *k) | |||
602 | 592 | ||
603 | static void mca_data_alloc(struct btree *b, struct bkey *k, gfp_t gfp) | 593 | static void mca_data_alloc(struct btree *b, struct bkey *k, gfp_t gfp) |
604 | { | 594 | { |
605 | if (!bch_btree_keys_alloc(b, | 595 | if (!bch_btree_keys_alloc(&b->keys, |
606 | max_t(unsigned, | 596 | max_t(unsigned, |
607 | ilog2(b->c->btree_pages), | 597 | ilog2(b->c->btree_pages), |
608 | btree_order(k)), | 598 | btree_order(k)), |
@@ -642,9 +632,9 @@ static int mca_reap(struct btree *b, unsigned min_order, bool flush) | |||
642 | if (!down_write_trylock(&b->lock)) | 632 | if (!down_write_trylock(&b->lock)) |
643 | return -ENOMEM; | 633 | return -ENOMEM; |
644 | 634 | ||
645 | BUG_ON(btree_node_dirty(b) && !b->sets[0].data); | 635 | BUG_ON(btree_node_dirty(b) && !b->keys.set[0].data); |
646 | 636 | ||
647 | if (b->page_order < min_order) | 637 | if (b->keys.page_order < min_order) |
648 | goto out_unlock; | 638 | goto out_unlock; |
649 | 639 | ||
650 | if (!flush) { | 640 | if (!flush) { |
@@ -809,7 +799,7 @@ int bch_btree_cache_alloc(struct cache_set *c) | |||
809 | c->verify_data = mca_bucket_alloc(c, &ZERO_KEY, GFP_KERNEL); | 799 | c->verify_data = mca_bucket_alloc(c, &ZERO_KEY, GFP_KERNEL); |
810 | 800 | ||
811 | if (c->verify_data && | 801 | if (c->verify_data && |
812 | c->verify_data->sets[0].data) | 802 | c->verify_data->keys.set->data) |
813 | list_del_init(&c->verify_data->list); | 803 | list_del_init(&c->verify_data->list); |
814 | else | 804 | else |
815 | c->verify_data = NULL; | 805 | c->verify_data = NULL; |
@@ -907,7 +897,7 @@ static struct btree *mca_alloc(struct cache_set *c, struct bkey *k, int level) | |||
907 | list_for_each_entry(b, &c->btree_cache_freed, list) | 897 | list_for_each_entry(b, &c->btree_cache_freed, list) |
908 | if (!mca_reap(b, 0, false)) { | 898 | if (!mca_reap(b, 0, false)) { |
909 | mca_data_alloc(b, k, __GFP_NOWARN|GFP_NOIO); | 899 | mca_data_alloc(b, k, __GFP_NOWARN|GFP_NOIO); |
910 | if (!b->sets[0].data) | 900 | if (!b->keys.set[0].data) |
911 | goto err; | 901 | goto err; |
912 | else | 902 | else |
913 | goto out; | 903 | goto out; |
@@ -918,7 +908,7 @@ static struct btree *mca_alloc(struct cache_set *c, struct bkey *k, int level) | |||
918 | goto err; | 908 | goto err; |
919 | 909 | ||
920 | BUG_ON(!down_write_trylock(&b->lock)); | 910 | BUG_ON(!down_write_trylock(&b->lock)); |
921 | if (!b->sets->data) | 911 | if (!b->keys.set->data) |
922 | goto err; | 912 | goto err; |
923 | out: | 913 | out: |
924 | BUG_ON(b->io_mutex.count != 1); | 914 | BUG_ON(b->io_mutex.count != 1); |
@@ -929,15 +919,17 @@ out: | |||
929 | hlist_add_head_rcu(&b->hash, mca_hash(c, k)); | 919 | hlist_add_head_rcu(&b->hash, mca_hash(c, k)); |
930 | 920 | ||
931 | lock_set_subclass(&b->lock.dep_map, level + 1, _THIS_IP_); | 921 | lock_set_subclass(&b->lock.dep_map, level + 1, _THIS_IP_); |
932 | b->level = level; | ||
933 | b->parent = (void *) ~0UL; | 922 | b->parent = (void *) ~0UL; |
923 | b->flags = 0; | ||
924 | b->written = 0; | ||
925 | b->level = level; | ||
934 | 926 | ||
935 | if (!b->level) | 927 | if (!b->level) |
936 | b->ops = &bch_extent_keys_ops; | 928 | bch_btree_keys_init(&b->keys, &bch_extent_keys_ops, |
929 | &b->c->expensive_debug_checks); | ||
937 | else | 930 | else |
938 | b->ops = &bch_btree_keys_ops; | 931 | bch_btree_keys_init(&b->keys, &bch_btree_keys_ops, |
939 | 932 | &b->c->expensive_debug_checks); | |
940 | mca_reinit(b); | ||
941 | 933 | ||
942 | return b; | 934 | return b; |
943 | err: | 935 | err: |
@@ -998,13 +990,13 @@ retry: | |||
998 | 990 | ||
999 | b->accessed = 1; | 991 | b->accessed = 1; |
1000 | 992 | ||
1001 | for (; i <= b->nsets && b->sets[i].size; i++) { | 993 | for (; i <= b->keys.nsets && b->keys.set[i].size; i++) { |
1002 | prefetch(b->sets[i].tree); | 994 | prefetch(b->keys.set[i].tree); |
1003 | prefetch(b->sets[i].data); | 995 | prefetch(b->keys.set[i].data); |
1004 | } | 996 | } |
1005 | 997 | ||
1006 | for (; i <= b->nsets; i++) | 998 | for (; i <= b->keys.nsets; i++) |
1007 | prefetch(b->sets[i].data); | 999 | prefetch(b->keys.set[i].data); |
1008 | 1000 | ||
1009 | if (btree_node_io_error(b)) { | 1001 | if (btree_node_io_error(b)) { |
1010 | rw_unlock(write, b); | 1002 | rw_unlock(write, b); |
@@ -1084,7 +1076,7 @@ retry: | |||
1084 | } | 1076 | } |
1085 | 1077 | ||
1086 | b->accessed = 1; | 1078 | b->accessed = 1; |
1087 | bch_bset_init_next(b, b->sets->data, bset_magic(&b->c->sb)); | 1079 | bch_bset_init_next(&b->keys, b->keys.set->data, bset_magic(&b->c->sb)); |
1088 | 1080 | ||
1089 | mutex_unlock(&c->bucket_lock); | 1081 | mutex_unlock(&c->bucket_lock); |
1090 | 1082 | ||
@@ -1215,7 +1207,7 @@ static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc) | |||
1215 | stale = max(stale, btree_mark_key(b, k)); | 1207 | stale = max(stale, btree_mark_key(b, k)); |
1216 | keys++; | 1208 | keys++; |
1217 | 1209 | ||
1218 | if (bch_ptr_bad(b, k)) | 1210 | if (bch_ptr_bad(&b->keys, k)) |
1219 | continue; | 1211 | continue; |
1220 | 1212 | ||
1221 | gc->key_bytes += bkey_u64s(k); | 1213 | gc->key_bytes += bkey_u64s(k); |
@@ -1225,9 +1217,9 @@ static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc) | |||
1225 | gc->data += KEY_SIZE(k); | 1217 | gc->data += KEY_SIZE(k); |
1226 | } | 1218 | } |
1227 | 1219 | ||
1228 | for (t = b->sets; t <= &b->sets[b->nsets]; t++) | 1220 | for (t = b->keys.set; t <= &b->keys.set[b->keys.nsets]; t++) |
1229 | btree_bug_on(t->size && | 1221 | btree_bug_on(t->size && |
1230 | bset_written(b, t) && | 1222 | bset_written(&b->keys, t) && |
1231 | bkey_cmp(&b->key, &t->end) < 0, | 1223 | bkey_cmp(&b->key, &t->end) < 0, |
1232 | b, "found short btree key in gc"); | 1224 | b, "found short btree key in gc"); |
1233 | 1225 | ||
@@ -1271,7 +1263,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, | |||
1271 | blocks = btree_default_blocks(b->c) * 2 / 3; | 1263 | blocks = btree_default_blocks(b->c) * 2 / 3; |
1272 | 1264 | ||
1273 | if (nodes < 2 || | 1265 | if (nodes < 2 || |
1274 | __set_blocks(b->sets[0].data, keys, | 1266 | __set_blocks(b->keys.set[0].data, keys, |
1275 | block_bytes(b->c)) > blocks * (nodes - 1)) | 1267 | block_bytes(b->c)) > blocks * (nodes - 1)) |
1276 | return 0; | 1268 | return 0; |
1277 | 1269 | ||
@@ -1428,7 +1420,7 @@ static int btree_gc_recurse(struct btree *b, struct btree_op *op, | |||
1428 | r[i].b = ERR_PTR(-EINTR); | 1420 | r[i].b = ERR_PTR(-EINTR); |
1429 | 1421 | ||
1430 | while (1) { | 1422 | while (1) { |
1431 | k = bch_btree_iter_next_filter(&iter, b, bch_ptr_bad); | 1423 | k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad); |
1432 | if (k) { | 1424 | if (k) { |
1433 | r->b = bch_btree_node_get(b->c, k, b->level - 1, true); | 1425 | r->b = bch_btree_node_get(b->c, k, b->level - 1, true); |
1434 | if (IS_ERR(r->b)) { | 1426 | if (IS_ERR(r->b)) { |
@@ -1764,7 +1756,8 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op, | |||
1764 | bch_btree_iter_init(b, &iter, NULL); | 1756 | bch_btree_iter_init(b, &iter, NULL); |
1765 | 1757 | ||
1766 | do { | 1758 | do { |
1767 | k = bch_btree_iter_next_filter(&iter, b, bch_ptr_bad); | 1759 | k = bch_btree_iter_next_filter(&iter, &b->keys, |
1760 | bch_ptr_bad); | ||
1768 | if (k) | 1761 | if (k) |
1769 | btree_node_prefetch(b->c, k, b->level - 1); | 1762 | btree_node_prefetch(b->c, k, b->level - 1); |
1770 | 1763 | ||
@@ -1894,7 +1887,7 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1894 | 1887 | ||
1895 | subtract_dirty(k, KEY_START(insert), KEY_SIZE(insert)); | 1888 | subtract_dirty(k, KEY_START(insert), KEY_SIZE(insert)); |
1896 | 1889 | ||
1897 | if (bkey_written(b, k)) { | 1890 | if (bkey_written(&b->keys, k)) { |
1898 | /* | 1891 | /* |
1899 | * We insert a new key to cover the top of the | 1892 | * We insert a new key to cover the top of the |
1900 | * old key, and the old key is modified in place | 1893 | * old key, and the old key is modified in place |
@@ -1907,19 +1900,20 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1907 | * depends on us inserting a new key for the top | 1900 | * depends on us inserting a new key for the top |
1908 | * here. | 1901 | * here. |
1909 | */ | 1902 | */ |
1910 | top = bch_bset_search(b, bset_tree_last(b), | 1903 | top = bch_bset_search(b, |
1904 | bset_tree_last(&b->keys), | ||
1911 | insert); | 1905 | insert); |
1912 | bch_bset_insert(b, top, k); | 1906 | bch_bset_insert(&b->keys, top, k); |
1913 | } else { | 1907 | } else { |
1914 | BKEY_PADDED(key) temp; | 1908 | BKEY_PADDED(key) temp; |
1915 | bkey_copy(&temp.key, k); | 1909 | bkey_copy(&temp.key, k); |
1916 | bch_bset_insert(b, k, &temp.key); | 1910 | bch_bset_insert(&b->keys, k, &temp.key); |
1917 | top = bkey_next(k); | 1911 | top = bkey_next(k); |
1918 | } | 1912 | } |
1919 | 1913 | ||
1920 | bch_cut_front(insert, top); | 1914 | bch_cut_front(insert, top); |
1921 | bch_cut_back(&START_KEY(insert), k); | 1915 | bch_cut_back(&START_KEY(insert), k); |
1922 | bch_bset_fix_invalidated_key(b, k); | 1916 | bch_bset_fix_invalidated_key(&b->keys, k); |
1923 | return false; | 1917 | return false; |
1924 | } | 1918 | } |
1925 | 1919 | ||
@@ -1929,7 +1923,7 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1929 | if (bkey_cmp(&START_KEY(insert), &START_KEY(k)) > 0) | 1923 | if (bkey_cmp(&START_KEY(insert), &START_KEY(k)) > 0) |
1930 | old_offset = KEY_START(insert); | 1924 | old_offset = KEY_START(insert); |
1931 | 1925 | ||
1932 | if (bkey_written(b, k) && | 1926 | if (bkey_written(&b->keys, k) && |
1933 | bkey_cmp(&START_KEY(insert), &START_KEY(k)) <= 0) { | 1927 | bkey_cmp(&START_KEY(insert), &START_KEY(k)) <= 0) { |
1934 | /* | 1928 | /* |
1935 | * Completely overwrote, so we don't have to | 1929 | * Completely overwrote, so we don't have to |
@@ -1938,7 +1932,7 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1938 | bch_cut_front(k, k); | 1932 | bch_cut_front(k, k); |
1939 | } else { | 1933 | } else { |
1940 | __bch_cut_back(&START_KEY(insert), k); | 1934 | __bch_cut_back(&START_KEY(insert), k); |
1941 | bch_bset_fix_invalidated_key(b, k); | 1935 | bch_bset_fix_invalidated_key(&b->keys, k); |
1942 | } | 1936 | } |
1943 | } | 1937 | } |
1944 | 1938 | ||
@@ -1979,7 +1973,8 @@ static bool btree_insert_key(struct btree *b, struct btree_op *op, | |||
1979 | * the previous key. | 1973 | * the previous key. |
1980 | */ | 1974 | */ |
1981 | prev = NULL; | 1975 | prev = NULL; |
1982 | m = bch_btree_iter_init(b, &iter, PRECEDING_KEY(&START_KEY(k))); | 1976 | m = bch_btree_iter_init(b, &iter, |
1977 | PRECEDING_KEY(&START_KEY(k))); | ||
1983 | 1978 | ||
1984 | if (fix_overlapping_extents(b, k, &iter, replace_key)) { | 1979 | if (fix_overlapping_extents(b, k, &iter, replace_key)) { |
1985 | op->insert_collision = true; | 1980 | op->insert_collision = true; |
@@ -2000,7 +1995,7 @@ static bool btree_insert_key(struct btree *b, struct btree_op *op, | |||
2000 | /* prev is in the tree, if we merge we're done */ | 1995 | /* prev is in the tree, if we merge we're done */ |
2001 | status = BTREE_INSERT_STATUS_BACK_MERGE; | 1996 | status = BTREE_INSERT_STATUS_BACK_MERGE; |
2002 | if (prev && | 1997 | if (prev && |
2003 | bch_bkey_try_merge(b, prev, k)) | 1998 | bch_bkey_try_merge(&b->keys, prev, k)) |
2004 | goto merged; | 1999 | goto merged; |
2005 | 2000 | ||
2006 | status = BTREE_INSERT_STATUS_OVERWROTE; | 2001 | status = BTREE_INSERT_STATUS_OVERWROTE; |
@@ -2010,14 +2005,14 @@ static bool btree_insert_key(struct btree *b, struct btree_op *op, | |||
2010 | 2005 | ||
2011 | status = BTREE_INSERT_STATUS_FRONT_MERGE; | 2006 | status = BTREE_INSERT_STATUS_FRONT_MERGE; |
2012 | if (m != bset_bkey_last(i) && | 2007 | if (m != bset_bkey_last(i) && |
2013 | bch_bkey_try_merge(b, k, m)) | 2008 | bch_bkey_try_merge(&b->keys, k, m)) |
2014 | goto copy; | 2009 | goto copy; |
2015 | } else { | 2010 | } else { |
2016 | BUG_ON(replace_key); | 2011 | BUG_ON(replace_key); |
2017 | m = bch_bset_search(b, bset_tree_last(b), k); | 2012 | m = bch_bset_search(b, bset_tree_last(&b->keys), k); |
2018 | } | 2013 | } |
2019 | 2014 | ||
2020 | insert: bch_bset_insert(b, m, k); | 2015 | insert: bch_bset_insert(&b->keys, m, k); |
2021 | copy: bkey_copy(m, k); | 2016 | copy: bkey_copy(m, k); |
2022 | merged: | 2017 | merged: |
2023 | bch_check_keys(b, "%u for %s", status, | 2018 | bch_check_keys(b, "%u for %s", status, |
@@ -2362,7 +2357,7 @@ static int bch_btree_map_nodes_recurse(struct btree *b, struct btree_op *op, | |||
2362 | 2357 | ||
2363 | bch_btree_iter_init(b, &iter, from); | 2358 | bch_btree_iter_init(b, &iter, from); |
2364 | 2359 | ||
2365 | while ((k = bch_btree_iter_next_filter(&iter, b, | 2360 | while ((k = bch_btree_iter_next_filter(&iter, &b->keys, |
2366 | bch_ptr_bad))) { | 2361 | bch_ptr_bad))) { |
2367 | ret = btree(map_nodes_recurse, k, b, | 2362 | ret = btree(map_nodes_recurse, k, b, |
2368 | op, from, fn, flags); | 2363 | op, from, fn, flags); |
@@ -2395,7 +2390,7 @@ static int bch_btree_map_keys_recurse(struct btree *b, struct btree_op *op, | |||
2395 | 2390 | ||
2396 | bch_btree_iter_init(b, &iter, from); | 2391 | bch_btree_iter_init(b, &iter, from); |
2397 | 2392 | ||
2398 | while ((k = bch_btree_iter_next_filter(&iter, b, bch_ptr_bad))) { | 2393 | while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) { |
2399 | ret = !b->level | 2394 | ret = !b->level |
2400 | ? fn(op, b, k) | 2395 | ? fn(op, b, k) |
2401 | : btree(map_keys_recurse, k, b, op, from, fn, flags); | 2396 | : btree(map_keys_recurse, k, b, op, from, fn, flags); |
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index 0b436079db71..04e81f8ab89a 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h | |||
@@ -113,28 +113,7 @@ struct btree_write { | |||
113 | int prio_blocked; | 113 | int prio_blocked; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct btree_keys_ops { | ||
117 | bool (*sort_cmp)(struct btree_iter_set, | ||
118 | struct btree_iter_set); | ||
119 | struct bkey *(*sort_fixup)(struct btree_iter *, | ||
120 | struct bkey *); | ||
121 | bool (*key_invalid)(struct btree *, | ||
122 | const struct bkey *); | ||
123 | bool (*key_bad)(struct btree *, | ||
124 | const struct bkey *); | ||
125 | bool (*key_merge)(struct btree *, | ||
126 | struct bkey *, struct bkey *); | ||
127 | |||
128 | |||
129 | /* | ||
130 | * Only used for deciding whether to use START_KEY(k) or just the key | ||
131 | * itself in a couple places | ||
132 | */ | ||
133 | bool is_extents; | ||
134 | }; | ||
135 | |||
136 | struct btree { | 116 | struct btree { |
137 | const struct btree_keys_ops *ops; | ||
138 | /* Hottest entries first */ | 117 | /* Hottest entries first */ |
139 | struct hlist_node hash; | 118 | struct hlist_node hash; |
140 | 119 | ||
@@ -151,17 +130,8 @@ struct btree { | |||
151 | unsigned long flags; | 130 | unsigned long flags; |
152 | uint16_t written; /* would be nice to kill */ | 131 | uint16_t written; /* would be nice to kill */ |
153 | uint8_t level; | 132 | uint8_t level; |
154 | uint8_t nsets; | 133 | |
155 | uint8_t page_order; | 134 | struct btree_keys keys; |
156 | |||
157 | /* | ||
158 | * Set of sorted keys - the real btree node - plus a binary search tree | ||
159 | * | ||
160 | * sets[0] is special; set[0]->tree, set[0]->prev and set[0]->data point | ||
161 | * to the memory we have allocated for this btree node. Additionally, | ||
162 | * set[0]->data points to the entire btree node as it exists on disk. | ||
163 | */ | ||
164 | struct bset_tree sets[MAX_BSETS]; | ||
165 | 135 | ||
166 | /* For outstanding btree writes, used as a lock - protects write_idx */ | 136 | /* For outstanding btree writes, used as a lock - protects write_idx */ |
167 | struct closure io; | 137 | struct closure io; |
@@ -201,49 +171,19 @@ static inline struct btree_write *btree_prev_write(struct btree *b) | |||
201 | return b->writes + (btree_node_write_idx(b) ^ 1); | 171 | return b->writes + (btree_node_write_idx(b) ^ 1); |
202 | } | 172 | } |
203 | 173 | ||
204 | static inline struct bset_tree *bset_tree_last(struct btree *b) | ||
205 | { | ||
206 | return b->sets + b->nsets; | ||
207 | } | ||
208 | |||
209 | static inline struct bset *btree_bset_first(struct btree *b) | 174 | static inline struct bset *btree_bset_first(struct btree *b) |
210 | { | 175 | { |
211 | return b->sets->data; | 176 | return b->keys.set->data; |
212 | } | 177 | } |
213 | 178 | ||
214 | static inline struct bset *btree_bset_last(struct btree *b) | 179 | static inline struct bset *btree_bset_last(struct btree *b) |
215 | { | 180 | { |
216 | return bset_tree_last(b)->data; | 181 | return bset_tree_last(&b->keys)->data; |
217 | } | ||
218 | |||
219 | static inline unsigned bset_byte_offset(struct btree *b, struct bset *i) | ||
220 | { | ||
221 | return ((size_t) i) - ((size_t) b->sets->data); | ||
222 | } | ||
223 | |||
224 | static inline unsigned bset_sector_offset(struct btree *b, struct bset *i) | ||
225 | { | ||
226 | return (((void *) i) - ((void *) btree_bset_first(b))) >> 9; | ||
227 | } | 182 | } |
228 | 183 | ||
229 | static inline unsigned bset_block_offset(struct btree *b, struct bset *i) | 184 | static inline unsigned bset_block_offset(struct btree *b, struct bset *i) |
230 | { | 185 | { |
231 | return bset_sector_offset(b, i) >> b->c->block_bits; | 186 | return bset_sector_offset(&b->keys, i) >> b->c->block_bits; |
232 | } | ||
233 | |||
234 | static inline struct bset *write_block(struct btree *b) | ||
235 | { | ||
236 | return ((void *) b->sets[0].data) + b->written * block_bytes(b->c); | ||
237 | } | ||
238 | |||
239 | static inline bool bset_written(struct btree *b, struct bset_tree *t) | ||
240 | { | ||
241 | return t->data < write_block(b); | ||
242 | } | ||
243 | |||
244 | static inline bool bkey_written(struct btree *b, struct bkey *k) | ||
245 | { | ||
246 | return k < write_block(b)->start; | ||
247 | } | 187 | } |
248 | 188 | ||
249 | static inline void set_gc_sectors(struct cache_set *c) | 189 | static inline void set_gc_sectors(struct cache_set *c) |
@@ -251,27 +191,6 @@ static inline void set_gc_sectors(struct cache_set *c) | |||
251 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 16); | 191 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 16); |
252 | } | 192 | } |
253 | 193 | ||
254 | static inline bool bch_ptr_invalid(struct btree *b, const struct bkey *k) | ||
255 | { | ||
256 | return b->ops->key_invalid(b, k); | ||
257 | } | ||
258 | |||
259 | static inline bool bch_ptr_bad(struct btree *b, const struct bkey *k) | ||
260 | { | ||
261 | return b->ops->key_bad(b, k); | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * Tries to merge l and r: l should be lower than r | ||
266 | * Returns true if we were able to merge. If we did merge, l will be the merged | ||
267 | * key, r will be untouched. | ||
268 | */ | ||
269 | static inline bool bch_bkey_try_merge(struct btree *b, | ||
270 | struct bkey *l, struct bkey *r) | ||
271 | { | ||
272 | return b->ops->key_merge ? b->ops->key_merge(b, l, r) : false; | ||
273 | } | ||
274 | |||
275 | void bkey_put(struct cache_set *c, struct bkey *k); | 194 | void bkey_put(struct cache_set *c, struct bkey *k); |
276 | 195 | ||
277 | /* Looping macros */ | 196 | /* Looping macros */ |
@@ -284,7 +203,7 @@ void bkey_put(struct cache_set *c, struct bkey *k); | |||
284 | 203 | ||
285 | #define for_each_key_filter(b, k, iter, filter) \ | 204 | #define for_each_key_filter(b, k, iter, filter) \ |
286 | for (bch_btree_iter_init((b), (iter), NULL); \ | 205 | for (bch_btree_iter_init((b), (iter), NULL); \ |
287 | ((k) = bch_btree_iter_next_filter((iter), b, filter));) | 206 | ((k) = bch_btree_iter_next_filter((iter), &(b)->keys, filter));) |
288 | 207 | ||
289 | #define for_each_key(b, k, iter) \ | 208 | #define for_each_key(b, k, iter) \ |
290 | for (bch_btree_iter_init((b), (iter), NULL); \ | 209 | for (bch_btree_iter_init((b), (iter), NULL); \ |
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c index 2c6587d016db..8acc18af07c1 100644 --- a/drivers/md/bcache/debug.c +++ b/drivers/md/bcache/debug.c | |||
@@ -113,9 +113,9 @@ static void bch_dump_bucket(struct btree *b) | |||
113 | unsigned i; | 113 | unsigned i; |
114 | 114 | ||
115 | console_lock(); | 115 | console_lock(); |
116 | for (i = 0; i <= b->nsets; i++) | 116 | for (i = 0; i <= b->keys.nsets; i++) |
117 | dump_bset(b, b->sets[i].data, | 117 | dump_bset(b, b->keys.set[i].data, |
118 | bset_block_offset(b, b->sets[i].data)); | 118 | bset_block_offset(b, b->keys.set[i].data)); |
119 | console_unlock(); | 119 | console_unlock(); |
120 | } | 120 | } |
121 | 121 | ||
@@ -139,13 +139,13 @@ void bch_btree_verify(struct btree *b) | |||
139 | mutex_lock(&b->c->verify_lock); | 139 | mutex_lock(&b->c->verify_lock); |
140 | 140 | ||
141 | ondisk = b->c->verify_ondisk; | 141 | ondisk = b->c->verify_ondisk; |
142 | sorted = b->c->verify_data->sets->data; | 142 | sorted = b->c->verify_data->keys.set->data; |
143 | inmemory = b->sets->data; | 143 | inmemory = b->keys.set->data; |
144 | 144 | ||
145 | bkey_copy(&v->key, &b->key); | 145 | bkey_copy(&v->key, &b->key); |
146 | v->written = 0; | 146 | v->written = 0; |
147 | v->level = b->level; | 147 | v->level = b->level; |
148 | v->ops = b->ops; | 148 | v->keys.ops = b->keys.ops; |
149 | 149 | ||
150 | bio = bch_bbio_alloc(b->c); | 150 | bio = bch_bbio_alloc(b->c); |
151 | bio->bi_bdev = PTR_CACHE(b->c, &b->key, 0)->bdev; | 151 | bio->bi_bdev = PTR_CACHE(b->c, &b->key, 0)->bdev; |
@@ -159,7 +159,7 @@ void bch_btree_verify(struct btree *b) | |||
159 | memcpy(ondisk, sorted, KEY_SIZE(&v->key) << 9); | 159 | memcpy(ondisk, sorted, KEY_SIZE(&v->key) << 9); |
160 | 160 | ||
161 | bch_btree_node_read_done(v); | 161 | bch_btree_node_read_done(v); |
162 | sorted = v->sets->data; | 162 | sorted = v->keys.set->data; |
163 | 163 | ||
164 | if (inmemory->keys != sorted->keys || | 164 | if (inmemory->keys != sorted->keys || |
165 | memcmp(inmemory->start, | 165 | memcmp(inmemory->start, |
@@ -264,14 +264,14 @@ void __bch_check_keys(struct btree *b, const char *fmt, ...) | |||
264 | if (p && bkey_cmp(&START_KEY(p), &START_KEY(k)) > 0) | 264 | if (p && bkey_cmp(&START_KEY(p), &START_KEY(k)) > 0) |
265 | goto bug; | 265 | goto bug; |
266 | 266 | ||
267 | if (bch_ptr_invalid(b, k)) | 267 | if (bch_ptr_invalid(&b->keys, k)) |
268 | continue; | 268 | continue; |
269 | 269 | ||
270 | err = "Overlapping keys"; | 270 | err = "Overlapping keys"; |
271 | if (p && bkey_cmp(p, &START_KEY(k)) > 0) | 271 | if (p && bkey_cmp(p, &START_KEY(k)) > 0) |
272 | goto bug; | 272 | goto bug; |
273 | } else { | 273 | } else { |
274 | if (bch_ptr_bad(b, k)) | 274 | if (bch_ptr_bad(&b->keys, k)) |
275 | continue; | 275 | continue; |
276 | 276 | ||
277 | err = "Duplicate keys"; | 277 | err = "Duplicate keys"; |
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c index 8fe6aaece41d..ba3021128e7a 100644 --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c | |||
@@ -81,8 +81,9 @@ bad: | |||
81 | return true; | 81 | return true; |
82 | } | 82 | } |
83 | 83 | ||
84 | static bool bch_btree_ptr_invalid(struct btree *b, const struct bkey *k) | 84 | static bool bch_btree_ptr_invalid(struct btree_keys *bk, const struct bkey *k) |
85 | { | 85 | { |
86 | struct btree *b = container_of(bk, struct btree, keys); | ||
86 | return __bch_btree_ptr_invalid(b->c, k); | 87 | return __bch_btree_ptr_invalid(b->c, k); |
87 | } | 88 | } |
88 | 89 | ||
@@ -118,13 +119,14 @@ err: | |||
118 | return true; | 119 | return true; |
119 | } | 120 | } |
120 | 121 | ||
121 | static bool bch_btree_ptr_bad(struct btree *b, const struct bkey *k) | 122 | static bool bch_btree_ptr_bad(struct btree_keys *bk, const struct bkey *k) |
122 | { | 123 | { |
124 | struct btree *b = container_of(bk, struct btree, keys); | ||
123 | unsigned i; | 125 | unsigned i; |
124 | 126 | ||
125 | if (!bkey_cmp(k, &ZERO_KEY) || | 127 | if (!bkey_cmp(k, &ZERO_KEY) || |
126 | !KEY_PTRS(k) || | 128 | !KEY_PTRS(k) || |
127 | bch_ptr_invalid(b, k)) | 129 | bch_ptr_invalid(bk, k)) |
128 | return true; | 130 | return true; |
129 | 131 | ||
130 | for (i = 0; i < KEY_PTRS(k); i++) | 132 | for (i = 0; i < KEY_PTRS(k); i++) |
@@ -209,8 +211,9 @@ static struct bkey *bch_extent_sort_fixup(struct btree_iter *iter, | |||
209 | return NULL; | 211 | return NULL; |
210 | } | 212 | } |
211 | 213 | ||
212 | static bool bch_extent_invalid(struct btree *b, const struct bkey *k) | 214 | static bool bch_extent_invalid(struct btree_keys *bk, const struct bkey *k) |
213 | { | 215 | { |
216 | struct btree *b = container_of(bk, struct btree, keys); | ||
214 | char buf[80]; | 217 | char buf[80]; |
215 | 218 | ||
216 | if (!KEY_SIZE(k)) | 219 | if (!KEY_SIZE(k)) |
@@ -259,13 +262,14 @@ err: | |||
259 | return true; | 262 | return true; |
260 | } | 263 | } |
261 | 264 | ||
262 | static bool bch_extent_bad(struct btree *b, const struct bkey *k) | 265 | static bool bch_extent_bad(struct btree_keys *bk, const struct bkey *k) |
263 | { | 266 | { |
267 | struct btree *b = container_of(bk, struct btree, keys); | ||
264 | struct bucket *g; | 268 | struct bucket *g; |
265 | unsigned i, stale; | 269 | unsigned i, stale; |
266 | 270 | ||
267 | if (!KEY_PTRS(k) || | 271 | if (!KEY_PTRS(k) || |
268 | bch_extent_invalid(b, k)) | 272 | bch_extent_invalid(bk, k)) |
269 | return true; | 273 | return true; |
270 | 274 | ||
271 | for (i = 0; i < KEY_PTRS(k); i++) | 275 | for (i = 0; i < KEY_PTRS(k); i++) |
@@ -303,8 +307,9 @@ static uint64_t merge_chksums(struct bkey *l, struct bkey *r) | |||
303 | ~((uint64_t)1 << 63); | 307 | ~((uint64_t)1 << 63); |
304 | } | 308 | } |
305 | 309 | ||
306 | static bool bch_extent_merge(struct btree *b, struct bkey *l, struct bkey *r) | 310 | static bool bch_extent_merge(struct btree_keys *bk, struct bkey *l, struct bkey *r) |
307 | { | 311 | { |
312 | struct btree *b = container_of(bk, struct btree, keys); | ||
308 | unsigned i; | 313 | unsigned i; |
309 | 314 | ||
310 | if (key_merging_disabled(b->c)) | 315 | if (key_merging_disabled(b->c)) |
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 206c80fb27c1..7e175dbc76b0 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c | |||
@@ -433,7 +433,7 @@ lock_root: | |||
433 | 433 | ||
434 | mutex_lock(&c->bucket_lock); | 434 | mutex_lock(&c->bucket_lock); |
435 | list_for_each_entry(b, &c->btree_cache, list) | 435 | list_for_each_entry(b, &c->btree_cache, list) |
436 | ret += 1 << (b->page_order + PAGE_SHIFT); | 436 | ret += 1 << (b->keys.page_order + PAGE_SHIFT); |
437 | 437 | ||
438 | mutex_unlock(&c->bucket_lock); | 438 | mutex_unlock(&c->bucket_lock); |
439 | return ret; | 439 | return ret; |