diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-07-28 21:35:09 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-01-08 16:05:12 -0500 |
commit | 911c9610099f26e9e6ea3d1962ce24f53890b163 (patch) | |
tree | 21dc0ae5850dc64756974aedacc0380a3e01b12e /drivers/md | |
parent | fafff81cead78157099df1ee10af16cc51893ddc (diff) |
bcache: Split out sort_extent_cmp()
Only use extent comparison for comparing extents, so we're not using
START_KEY() on other key types (i.e. btree pointers)
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/bset.c | 84 | ||||
-rw-r--r-- | drivers/md/bcache/bset.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 10 | ||||
-rw-r--r-- | drivers/md/bcache/btree.h | 7 |
4 files changed, 73 insertions, 32 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index bfee926e35f0..9e3a53d87de0 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
@@ -855,19 +855,13 @@ struct bkey *__bch_bset_search(struct btree *b, struct bset_tree *t, | |||
855 | 855 | ||
856 | /* Btree iterator */ | 856 | /* Btree iterator */ |
857 | 857 | ||
858 | /* | 858 | typedef bool (btree_iter_cmp_fn)(struct btree_iter_set, |
859 | * Returns true if l > r - unless l == r, in which case returns true if l is | 859 | struct btree_iter_set); |
860 | * older than r. | 860 | |
861 | * | ||
862 | * Necessary for btree_sort_fixup() - if there are multiple keys that compare | ||
863 | * equal in different sets, we have to process them newest to oldest. | ||
864 | */ | ||
865 | static inline bool btree_iter_cmp(struct btree_iter_set l, | 861 | static inline bool btree_iter_cmp(struct btree_iter_set l, |
866 | struct btree_iter_set r) | 862 | struct btree_iter_set r) |
867 | { | 863 | { |
868 | int64_t c = bkey_cmp(&START_KEY(l.k), &START_KEY(r.k)); | 864 | return bkey_cmp(l.k, r.k) > 0; |
869 | |||
870 | return c ? c > 0 : l.k < r.k; | ||
871 | } | 865 | } |
872 | 866 | ||
873 | static inline bool btree_iter_end(struct btree_iter *iter) | 867 | static inline bool btree_iter_end(struct btree_iter *iter) |
@@ -884,8 +878,10 @@ void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, | |||
884 | btree_iter_cmp)); | 878 | btree_iter_cmp)); |
885 | } | 879 | } |
886 | 880 | ||
887 | struct bkey *__bch_btree_iter_init(struct btree *b, struct btree_iter *iter, | 881 | static struct bkey *__bch_btree_iter_init(struct btree *b, |
888 | struct bkey *search, struct bset_tree *start) | 882 | struct btree_iter *iter, |
883 | struct bkey *search, | ||
884 | struct bset_tree *start) | ||
889 | { | 885 | { |
890 | struct bkey *ret = NULL; | 886 | struct bkey *ret = NULL; |
891 | iter->size = ARRAY_SIZE(iter->data); | 887 | iter->size = ARRAY_SIZE(iter->data); |
@@ -903,7 +899,15 @@ struct bkey *__bch_btree_iter_init(struct btree *b, struct btree_iter *iter, | |||
903 | return ret; | 899 | return ret; |
904 | } | 900 | } |
905 | 901 | ||
906 | struct bkey *bch_btree_iter_next(struct btree_iter *iter) | 902 | struct bkey *bch_btree_iter_init(struct btree *b, |
903 | struct btree_iter *iter, | ||
904 | struct bkey *search) | ||
905 | { | ||
906 | return __bch_btree_iter_init(b, iter, search, b->sets); | ||
907 | } | ||
908 | |||
909 | static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, | ||
910 | btree_iter_cmp_fn *cmp) | ||
907 | { | 911 | { |
908 | struct btree_iter_set unused; | 912 | struct btree_iter_set unused; |
909 | struct bkey *ret = NULL; | 913 | struct bkey *ret = NULL; |
@@ -920,14 +924,20 @@ struct bkey *bch_btree_iter_next(struct btree_iter *iter) | |||
920 | } | 924 | } |
921 | 925 | ||
922 | if (iter->data->k == iter->data->end) | 926 | if (iter->data->k == iter->data->end) |
923 | heap_pop(iter, unused, btree_iter_cmp); | 927 | heap_pop(iter, unused, cmp); |
924 | else | 928 | else |
925 | heap_sift(iter, 0, btree_iter_cmp); | 929 | heap_sift(iter, 0, cmp); |
926 | } | 930 | } |
927 | 931 | ||
928 | return ret; | 932 | return ret; |
929 | } | 933 | } |
930 | 934 | ||
935 | struct bkey *bch_btree_iter_next(struct btree_iter *iter) | ||
936 | { | ||
937 | return __bch_btree_iter_next(iter, btree_iter_cmp); | ||
938 | |||
939 | } | ||
940 | |||
931 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter, | 941 | struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter, |
932 | struct btree *b, ptr_filter_fn fn) | 942 | struct btree *b, ptr_filter_fn fn) |
933 | { | 943 | { |
@@ -951,13 +961,37 @@ static void sort_key_next(struct btree_iter *iter, | |||
951 | *i = iter->data[--iter->used]; | 961 | *i = iter->data[--iter->used]; |
952 | } | 962 | } |
953 | 963 | ||
954 | static struct bkey *btree_sort_fixup(struct btree_iter *iter, struct bkey *tmp) | 964 | /* |
965 | * Returns true if l > r - unless l == r, in which case returns true if l is | ||
966 | * older than r. | ||
967 | * | ||
968 | * Necessary for btree_sort_fixup() - if there are multiple keys that compare | ||
969 | * equal in different sets, we have to process them newest to oldest. | ||
970 | */ | ||
971 | static inline bool sort_extent_cmp(struct btree_iter_set l, | ||
972 | struct btree_iter_set r) | ||
973 | { | ||
974 | int64_t c = bkey_cmp(&START_KEY(l.k), &START_KEY(r.k)); | ||
975 | |||
976 | return c ? c > 0 : l.k < r.k; | ||
977 | } | ||
978 | |||
979 | static inline bool sort_cmp(struct btree_iter_set l, | ||
980 | struct btree_iter_set r) | ||
981 | { | ||
982 | int64_t c = bkey_cmp(l.k, r.k); | ||
983 | |||
984 | return c ? c > 0 : l.k < r.k; | ||
985 | } | ||
986 | |||
987 | static struct bkey *btree_sort_fixup_extents(struct btree_iter *iter, | ||
988 | struct bkey *tmp) | ||
955 | { | 989 | { |
956 | while (iter->used > 1) { | 990 | while (iter->used > 1) { |
957 | struct btree_iter_set *top = iter->data, *i = top + 1; | 991 | struct btree_iter_set *top = iter->data, *i = top + 1; |
958 | 992 | ||
959 | if (iter->used > 2 && | 993 | if (iter->used > 2 && |
960 | btree_iter_cmp(i[0], i[1])) | 994 | sort_extent_cmp(i[0], i[1])) |
961 | i++; | 995 | i++; |
962 | 996 | ||
963 | if (bkey_cmp(top->k, &START_KEY(i->k)) <= 0) | 997 | if (bkey_cmp(top->k, &START_KEY(i->k)) <= 0) |
@@ -965,7 +999,7 @@ static struct bkey *btree_sort_fixup(struct btree_iter *iter, struct bkey *tmp) | |||
965 | 999 | ||
966 | if (!KEY_SIZE(i->k)) { | 1000 | if (!KEY_SIZE(i->k)) { |
967 | sort_key_next(iter, i); | 1001 | sort_key_next(iter, i); |
968 | heap_sift(iter, i - top, btree_iter_cmp); | 1002 | heap_sift(iter, i - top, sort_extent_cmp); |
969 | continue; | 1003 | continue; |
970 | } | 1004 | } |
971 | 1005 | ||
@@ -975,7 +1009,7 @@ static struct bkey *btree_sort_fixup(struct btree_iter *iter, struct bkey *tmp) | |||
975 | else | 1009 | else |
976 | bch_cut_front(top->k, i->k); | 1010 | bch_cut_front(top->k, i->k); |
977 | 1011 | ||
978 | heap_sift(iter, i - top, btree_iter_cmp); | 1012 | heap_sift(iter, i - top, sort_extent_cmp); |
979 | } else { | 1013 | } else { |
980 | /* can't happen because of comparison func */ | 1014 | /* can't happen because of comparison func */ |
981 | BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k))); | 1015 | BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k))); |
@@ -1001,20 +1035,28 @@ static void btree_mergesort(struct btree *b, struct bset *out, | |||
1001 | struct btree_iter *iter, | 1035 | struct btree_iter *iter, |
1002 | bool fixup, bool remove_stale) | 1036 | bool fixup, bool remove_stale) |
1003 | { | 1037 | { |
1038 | int i; | ||
1004 | struct bkey *k, *last = NULL; | 1039 | struct bkey *k, *last = NULL; |
1005 | BKEY_PADDED(k) tmp; | 1040 | BKEY_PADDED(k) tmp; |
1041 | btree_iter_cmp_fn *cmp = b->level | ||
1042 | ? sort_cmp | ||
1043 | : sort_extent_cmp; | ||
1006 | bool (*bad)(struct btree *, const struct bkey *) = remove_stale | 1044 | bool (*bad)(struct btree *, const struct bkey *) = remove_stale |
1007 | ? bch_ptr_bad | 1045 | ? bch_ptr_bad |
1008 | : bch_ptr_invalid; | 1046 | : bch_ptr_invalid; |
1009 | 1047 | ||
1048 | /* Heapify the iterator, using our comparison function */ | ||
1049 | for (i = iter->used / 2 - 1; i >= 0; --i) | ||
1050 | heap_sift(iter, i, cmp); | ||
1051 | |||
1010 | while (!btree_iter_end(iter)) { | 1052 | while (!btree_iter_end(iter)) { |
1011 | if (fixup && !b->level) | 1053 | if (fixup && !b->level) |
1012 | k = btree_sort_fixup(iter, &tmp.k); | 1054 | k = btree_sort_fixup_extents(iter, &tmp.k); |
1013 | else | 1055 | else |
1014 | k = NULL; | 1056 | k = NULL; |
1015 | 1057 | ||
1016 | if (!k) | 1058 | if (!k) |
1017 | k = bch_btree_iter_next(iter); | 1059 | k = __bch_btree_iter_next(iter, cmp); |
1018 | 1060 | ||
1019 | if (bad(b, k)) | 1061 | if (bad(b, k)) |
1020 | continue; | 1062 | continue; |
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h index 88b6edbf508b..91bcbdb04085 100644 --- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h | |||
@@ -305,8 +305,8 @@ struct bkey *bch_btree_iter_next_filter(struct btree_iter *, | |||
305 | struct btree *, ptr_filter_fn); | 305 | struct btree *, ptr_filter_fn); |
306 | 306 | ||
307 | void bch_btree_iter_push(struct btree_iter *, struct bkey *, struct bkey *); | 307 | void bch_btree_iter_push(struct btree_iter *, struct bkey *, struct bkey *); |
308 | struct bkey *__bch_btree_iter_init(struct btree *, struct btree_iter *, | 308 | struct bkey *bch_btree_iter_init(struct btree *, struct btree_iter *, |
309 | struct bkey *, struct bset_tree *); | 309 | struct bkey *); |
310 | 310 | ||
311 | /* 32 bits total: */ | 311 | /* 32 bits total: */ |
312 | #define BKEY_MID_BITS 3 | 312 | #define BKEY_MID_BITS 3 |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 8aaaf16637a0..e1e36e761724 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -1854,10 +1854,16 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert, | |||
1854 | 1854 | ||
1855 | while (1) { | 1855 | while (1) { |
1856 | struct bkey *k = bch_btree_iter_next(iter); | 1856 | struct bkey *k = bch_btree_iter_next(iter); |
1857 | if (!k || | 1857 | if (!k) |
1858 | bkey_cmp(&START_KEY(k), insert) >= 0) | ||
1859 | break; | 1858 | break; |
1860 | 1859 | ||
1860 | if (bkey_cmp(&START_KEY(k), insert) >= 0) { | ||
1861 | if (KEY_SIZE(k)) | ||
1862 | break; | ||
1863 | else | ||
1864 | continue; | ||
1865 | } | ||
1866 | |||
1861 | if (bkey_cmp(k, &START_KEY(insert)) <= 0) | 1867 | if (bkey_cmp(k, &START_KEY(insert)) <= 0) |
1862 | continue; | 1868 | continue; |
1863 | 1869 | ||
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index 580b01137264..2a5a8481f25e 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h | |||
@@ -225,13 +225,6 @@ static inline void set_gc_sectors(struct cache_set *c) | |||
225 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 16); | 225 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 16); |
226 | } | 226 | } |
227 | 227 | ||
228 | static inline struct bkey *bch_btree_iter_init(struct btree *b, | ||
229 | struct btree_iter *iter, | ||
230 | struct bkey *search) | ||
231 | { | ||
232 | return __bch_btree_iter_init(b, iter, search, b->sets); | ||
233 | } | ||
234 | |||
235 | static inline bool bch_ptr_invalid(struct btree *b, const struct bkey *k) | 228 | static inline bool bch_ptr_invalid(struct btree *b, const struct bkey *k) |
236 | { | 229 | { |
237 | if (b->level) | 230 | if (b->level) |