aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-24 20:24:25 -0400
committerKent Overstreet <kmo@daterainc.com>2013-11-11 00:56:00 -0500
commitc2f95ae2ebbe1ab61b1d4437f5923fdf720d4d4d (patch)
tree67da94194f87693f7c280176cfc5a13c6162eea0
parent4f3d40147b8d0ce7055e241e1d263e0aa2b2b46d (diff)
bcache: Clean up keylist code
More random refactoring. Signed-off-by: Kent Overstreet <kmo@daterainc.com>
-rw-r--r--drivers/md/bcache/bset.c44
-rw-r--r--drivers/md/bcache/bset.h35
-rw-r--r--drivers/md/bcache/btree.c12
-rw-r--r--drivers/md/bcache/journal.c14
-rw-r--r--drivers/md/bcache/request.c4
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
17void 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
28int bch_keylist_realloc(struct keylist *l, int nptrs, struct cache_set *c) 17int 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
63struct bkey *bch_keylist_pop(struct keylist *l) 52struct 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
76void bch_keylist_pop_front(struct keylist *l) 65void 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
229struct keylist { 229struct 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
241static inline void bch_keylist_init(struct keylist *l) 244static 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
246static inline void bch_keylist_push(struct keylist *l) 249static 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
257static inline bool bch_keylist_empty(struct keylist *l) 260static 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
265static inline void bch_keylist_reset(struct keylist *l)
266{
267 l->top = l->keys;
260} 268}
261 269
262static inline void bch_keylist_free(struct keylist *l) 270static 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
276static inline size_t bch_keylist_nkeys(struct keylist *l)
277{
278 return l->top_p - l->keys_p;
279}
280
281static inline size_t bch_keylist_bytes(struct keylist *l)
282{
283 return bch_keylist_nkeys(l) * sizeof(uint64_t);
266} 284}
267 285
268void bch_keylist_copy(struct keylist *, struct keylist *);
269struct bkey *bch_keylist_pop(struct keylist *); 286struct bkey *bch_keylist_pop(struct keylist *);
270void bch_keylist_pop_front(struct keylist *); 287void bch_keylist_pop_front(struct keylist *);
271int bch_keylist_realloc(struct keylist *, int, struct cache_set *); 288int 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;