diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-07-24 20:24:25 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-11-11 00:56:00 -0500 |
commit | c2f95ae2ebbe1ab61b1d4437f5923fdf720d4d4d (patch) | |
tree | 67da94194f87693f7c280176cfc5a13c6162eea0 | |
parent | 4f3d40147b8d0ce7055e241e1d263e0aa2b2b46d (diff) |
bcache: Clean up keylist code
More random refactoring.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
-rw-r--r-- | drivers/md/bcache/bset.c | 44 | ||||
-rw-r--r-- | drivers/md/bcache/bset.h | 35 | ||||
-rw-r--r-- | drivers/md/bcache/btree.c | 12 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 14 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 4 |
5 files changed, 57 insertions, 52 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 830eede86d56..d0512e451dda 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
@@ -14,22 +14,12 @@ | |||
14 | 14 | ||
15 | /* Keylists */ | 15 | /* Keylists */ |
16 | 16 | ||
17 | void bch_keylist_copy(struct keylist *dest, struct keylist *src) | ||
18 | { | ||
19 | *dest = *src; | ||
20 | |||
21 | if (src->list == src->d) { | ||
22 | size_t n = (uint64_t *) src->top - src->d; | ||
23 | dest->top = (struct bkey *) &dest->d[n]; | ||
24 | dest->list = dest->d; | ||
25 | } | ||
26 | } | ||
27 | |||
28 | int bch_keylist_realloc(struct keylist *l, int nptrs, struct cache_set *c) | 17 | int bch_keylist_realloc(struct keylist *l, int nptrs, struct cache_set *c) |
29 | { | 18 | { |
30 | unsigned oldsize = (uint64_t *) l->top - l->list; | 19 | size_t oldsize = bch_keylist_nkeys(l); |
31 | unsigned newsize = oldsize + 2 + nptrs; | 20 | size_t newsize = oldsize + 2 + nptrs; |
32 | uint64_t *new; | 21 | uint64_t *old_keys = l->keys_p == l->inline_keys ? NULL : l->keys_p; |
22 | uint64_t *new_keys; | ||
33 | 23 | ||
34 | /* The journalling code doesn't handle the case where the keys to insert | 24 | /* The journalling code doesn't handle the case where the keys to insert |
35 | * is bigger than an empty write: If we just return -ENOMEM here, | 25 | * is bigger than an empty write: If we just return -ENOMEM here, |
@@ -45,24 +35,23 @@ int bch_keylist_realloc(struct keylist *l, int nptrs, struct cache_set *c) | |||
45 | roundup_pow_of_two(oldsize) == newsize) | 35 | roundup_pow_of_two(oldsize) == newsize) |
46 | return 0; | 36 | return 0; |
47 | 37 | ||
48 | new = krealloc(l->list == l->d ? NULL : l->list, | 38 | new_keys = krealloc(old_keys, sizeof(uint64_t) * newsize, GFP_NOIO); |
49 | sizeof(uint64_t) * newsize, GFP_NOIO); | ||
50 | 39 | ||
51 | if (!new) | 40 | if (!new_keys) |
52 | return -ENOMEM; | 41 | return -ENOMEM; |
53 | 42 | ||
54 | if (l->list == l->d) | 43 | if (!old_keys) |
55 | memcpy(new, l->list, sizeof(uint64_t) * KEYLIST_INLINE); | 44 | memcpy(new_keys, l->inline_keys, sizeof(uint64_t) * oldsize); |
56 | 45 | ||
57 | l->list = new; | 46 | l->keys_p = new_keys; |
58 | l->top = (struct bkey *) (&l->list[oldsize]); | 47 | l->top_p = new_keys + oldsize; |
59 | 48 | ||
60 | return 0; | 49 | return 0; |
61 | } | 50 | } |
62 | 51 | ||
63 | struct bkey *bch_keylist_pop(struct keylist *l) | 52 | struct bkey *bch_keylist_pop(struct keylist *l) |
64 | { | 53 | { |
65 | struct bkey *k = l->bottom; | 54 | struct bkey *k = l->keys; |
66 | 55 | ||
67 | if (k == l->top) | 56 | if (k == l->top) |
68 | return NULL; | 57 | return NULL; |
@@ -75,14 +64,11 @@ struct bkey *bch_keylist_pop(struct keylist *l) | |||
75 | 64 | ||
76 | void bch_keylist_pop_front(struct keylist *l) | 65 | void bch_keylist_pop_front(struct keylist *l) |
77 | { | 66 | { |
78 | struct bkey *next = bkey_next(l->bottom); | 67 | l->top_p -= bkey_u64s(l->keys); |
79 | size_t bytes = ((void *) l->top) - ((void *) next); | ||
80 | |||
81 | memmove(l->bottom, | ||
82 | next, | ||
83 | bytes); | ||
84 | 68 | ||
85 | l->top = ((void *) l->bottom) + bytes; | 69 | memmove(l->keys, |
70 | bkey_next(l->keys), | ||
71 | bch_keylist_bytes(l)); | ||
86 | } | 72 | } |
87 | 73 | ||
88 | /* Pointer validation */ | 74 | /* Pointer validation */ |
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h index a3627d0cd88b..8a9305685b7e 100644 --- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h | |||
@@ -227,20 +227,23 @@ static inline struct bkey *bkey_next(const struct bkey *k) | |||
227 | /* Keylists */ | 227 | /* Keylists */ |
228 | 228 | ||
229 | struct keylist { | 229 | struct keylist { |
230 | struct bkey *top; | ||
231 | union { | 230 | union { |
232 | uint64_t *list; | 231 | struct bkey *keys; |
233 | struct bkey *bottom; | 232 | uint64_t *keys_p; |
233 | }; | ||
234 | union { | ||
235 | struct bkey *top; | ||
236 | uint64_t *top_p; | ||
234 | }; | 237 | }; |
235 | 238 | ||
236 | /* Enough room for btree_split's keys without realloc */ | 239 | /* Enough room for btree_split's keys without realloc */ |
237 | #define KEYLIST_INLINE 16 | 240 | #define KEYLIST_INLINE 16 |
238 | uint64_t d[KEYLIST_INLINE]; | 241 | uint64_t inline_keys[KEYLIST_INLINE]; |
239 | }; | 242 | }; |
240 | 243 | ||
241 | static inline void bch_keylist_init(struct keylist *l) | 244 | static inline void bch_keylist_init(struct keylist *l) |
242 | { | 245 | { |
243 | l->top = (void *) (l->list = l->d); | 246 | l->top_p = l->keys_p = l->inline_keys; |
244 | } | 247 | } |
245 | 248 | ||
246 | static inline void bch_keylist_push(struct keylist *l) | 249 | static inline void bch_keylist_push(struct keylist *l) |
@@ -256,16 +259,30 @@ static inline void bch_keylist_add(struct keylist *l, struct bkey *k) | |||
256 | 259 | ||
257 | static inline bool bch_keylist_empty(struct keylist *l) | 260 | static inline bool bch_keylist_empty(struct keylist *l) |
258 | { | 261 | { |
259 | return l->top == (void *) l->list; | 262 | return l->top == l->keys; |
263 | } | ||
264 | |||
265 | static inline void bch_keylist_reset(struct keylist *l) | ||
266 | { | ||
267 | l->top = l->keys; | ||
260 | } | 268 | } |
261 | 269 | ||
262 | static inline void bch_keylist_free(struct keylist *l) | 270 | static inline void bch_keylist_free(struct keylist *l) |
263 | { | 271 | { |
264 | if (l->list != l->d) | 272 | if (l->keys_p != l->inline_keys) |
265 | kfree(l->list); | 273 | kfree(l->keys_p); |
274 | } | ||
275 | |||
276 | static inline size_t bch_keylist_nkeys(struct keylist *l) | ||
277 | { | ||
278 | return l->top_p - l->keys_p; | ||
279 | } | ||
280 | |||
281 | static inline size_t bch_keylist_bytes(struct keylist *l) | ||
282 | { | ||
283 | return bch_keylist_nkeys(l) * sizeof(uint64_t); | ||
266 | } | 284 | } |
267 | 285 | ||
268 | void bch_keylist_copy(struct keylist *, struct keylist *); | ||
269 | struct bkey *bch_keylist_pop(struct keylist *); | 286 | struct bkey *bch_keylist_pop(struct keylist *); |
270 | void bch_keylist_pop_front(struct keylist *); | 287 | void bch_keylist_pop_front(struct keylist *); |
271 | int bch_keylist_realloc(struct keylist *, int, struct cache_set *); | 288 | int bch_keylist_realloc(struct keylist *, int, struct cache_set *); |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index fc3cae5c94b2..f960607f1f25 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -1866,7 +1866,7 @@ static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op, | |||
1866 | 1866 | ||
1867 | while (!bch_keylist_empty(insert_keys)) { | 1867 | while (!bch_keylist_empty(insert_keys)) { |
1868 | struct bset *i = write_block(b); | 1868 | struct bset *i = write_block(b); |
1869 | struct bkey *k = insert_keys->bottom; | 1869 | struct bkey *k = insert_keys->keys; |
1870 | 1870 | ||
1871 | if (b->written + __set_blocks(i, i->keys + bkey_u64s(k), b->c) | 1871 | if (b->written + __set_blocks(i, i->keys + bkey_u64s(k), b->c) |
1872 | > btree_blocks(b)) | 1872 | > btree_blocks(b)) |
@@ -1887,10 +1887,10 @@ static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op, | |||
1887 | } | 1887 | } |
1888 | #endif | 1888 | #endif |
1889 | BKEY_PADDED(key) temp; | 1889 | BKEY_PADDED(key) temp; |
1890 | bkey_copy(&temp.key, insert_keys->bottom); | 1890 | bkey_copy(&temp.key, insert_keys->keys); |
1891 | 1891 | ||
1892 | bch_cut_back(&b->key, &temp.key); | 1892 | bch_cut_back(&b->key, &temp.key); |
1893 | bch_cut_front(&b->key, insert_keys->bottom); | 1893 | bch_cut_front(&b->key, insert_keys->keys); |
1894 | 1894 | ||
1895 | ret |= btree_insert_key(b, op, &temp.key); | 1895 | ret |= btree_insert_key(b, op, &temp.key); |
1896 | break; | 1896 | break; |
@@ -1984,7 +1984,7 @@ static int btree_split(struct btree *b, struct btree_op *op, | |||
1984 | } else if (!b->parent) { | 1984 | } else if (!b->parent) { |
1985 | /* Root filled up but didn't need to be split */ | 1985 | /* Root filled up but didn't need to be split */ |
1986 | 1986 | ||
1987 | parent_keys->top = parent_keys->bottom; | 1987 | bch_keylist_reset(parent_keys); |
1988 | closure_sync(&op->cl); | 1988 | closure_sync(&op->cl); |
1989 | bch_btree_set_root(n1); | 1989 | bch_btree_set_root(n1); |
1990 | } else { | 1990 | } else { |
@@ -2118,12 +2118,12 @@ static int bch_btree_insert_recurse(struct btree *b, struct btree_op *op, | |||
2118 | if (b->level) { | 2118 | if (b->level) { |
2119 | struct bkey *k; | 2119 | struct bkey *k; |
2120 | 2120 | ||
2121 | k = bch_next_recurse_key(b, &START_KEY(keys->bottom)); | 2121 | k = bch_next_recurse_key(b, &START_KEY(keys->keys)); |
2122 | if (!k) { | 2122 | if (!k) { |
2123 | btree_bug(b, "no key to recurse on at level %i/%i", | 2123 | btree_bug(b, "no key to recurse on at level %i/%i", |
2124 | b->level, b->c->root->level); | 2124 | b->level, b->c->root->level); |
2125 | 2125 | ||
2126 | keys->top = keys->bottom; | 2126 | bch_keylist_reset(keys); |
2127 | return -EIO; | 2127 | return -EIO; |
2128 | } | 2128 | } |
2129 | 2129 | ||
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index 5abe5d5fc183..1bdefdb1fa71 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c | |||
@@ -713,7 +713,7 @@ void bch_journal(struct closure *cl) | |||
713 | struct btree_op *op = container_of(cl, struct btree_op, cl); | 713 | struct btree_op *op = container_of(cl, struct btree_op, cl); |
714 | struct cache_set *c = op->c; | 714 | struct cache_set *c = op->c; |
715 | struct journal_write *w; | 715 | struct journal_write *w; |
716 | size_t b, n = ((uint64_t *) op->keys.top) - op->keys.list; | 716 | size_t sectors, nkeys; |
717 | 717 | ||
718 | if (op->type != BTREE_INSERT || | 718 | if (op->type != BTREE_INSERT || |
719 | !CACHE_SYNC(&c->sb)) | 719 | !CACHE_SYNC(&c->sb)) |
@@ -741,10 +741,12 @@ void bch_journal(struct closure *cl) | |||
741 | } | 741 | } |
742 | 742 | ||
743 | w = c->journal.cur; | 743 | w = c->journal.cur; |
744 | b = __set_blocks(w->data, w->data->keys + n, c); | 744 | nkeys = w->data->keys + bch_keylist_nkeys(&op->keys); |
745 | sectors = __set_blocks(w->data, nkeys, c) * c->sb.block_size; | ||
745 | 746 | ||
746 | if (b * c->sb.block_size > PAGE_SECTORS << JSET_BITS || | 747 | if (sectors > min_t(size_t, |
747 | b > c->journal.blocks_free) { | 748 | c->journal.blocks_free * c->sb.block_size, |
749 | PAGE_SECTORS << JSET_BITS)) { | ||
748 | trace_bcache_journal_entry_full(c); | 750 | trace_bcache_journal_entry_full(c); |
749 | 751 | ||
750 | /* | 752 | /* |
@@ -760,8 +762,8 @@ void bch_journal(struct closure *cl) | |||
760 | continue_at(cl, bch_journal, bcache_wq); | 762 | continue_at(cl, bch_journal, bcache_wq); |
761 | } | 763 | } |
762 | 764 | ||
763 | memcpy(end(w->data), op->keys.list, n * sizeof(uint64_t)); | 765 | memcpy(end(w->data), op->keys.keys, bch_keylist_bytes(&op->keys)); |
764 | w->data->keys += n; | 766 | w->data->keys += bch_keylist_nkeys(&op->keys); |
765 | 767 | ||
766 | op->journal = &fifo_back(&c->journal.pin); | 768 | op->journal = &fifo_back(&c->journal.pin); |
767 | atomic_inc(op->journal); | 769 | atomic_inc(op->journal); |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 7fd84ce9e835..a000e918b795 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -438,13 +438,13 @@ static void bch_insert_data_error(struct closure *cl) | |||
438 | * from the keys we'll accomplish just that. | 438 | * from the keys we'll accomplish just that. |
439 | */ | 439 | */ |
440 | 440 | ||
441 | struct bkey *src = op->keys.bottom, *dst = op->keys.bottom; | 441 | struct bkey *src = op->keys.keys, *dst = op->keys.keys; |
442 | 442 | ||
443 | while (src != op->keys.top) { | 443 | while (src != op->keys.top) { |
444 | struct bkey *n = bkey_next(src); | 444 | struct bkey *n = bkey_next(src); |
445 | 445 | ||
446 | SET_KEY_PTRS(src, 0); | 446 | SET_KEY_PTRS(src, 0); |
447 | bkey_copy(dst, src); | 447 | memmove(dst, src, bkey_bytes(src)); |
448 | 448 | ||
449 | dst = bkey_next(dst); | 449 | dst = bkey_next(dst); |
450 | src = n; | 450 | src = n; |