diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2015-05-28 23:46:24 -0700 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-18 20:57:10 -0900 |
commit | 3759e8982de153c493d9a18db4b3212e253de3ac (patch) | |
tree | 35bdaabb1b54f4d40cf87a0b5c9ca01a7e0f30f2 | |
parent | 758c5639d0f9961c6eeb0a3411f6687cbc430ab2 (diff) |
bcache: Take inline_keys out of struct keylist
this is to make keylist_single smaller, and because we're gonna need explicit
control over this soon
-rw-r--r-- | drivers/md/bcache/btree.c | 17 | ||||
-rw-r--r-- | drivers/md/bcache/dirent.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/gc.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 5 | ||||
-rw-r--r-- | drivers/md/bcache/io.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/keylist.c | 7 | ||||
-rw-r--r-- | drivers/md/bcache/keylist.h | 18 | ||||
-rw-r--r-- | drivers/md/bcache/keylist_types.h | 15 | ||||
-rw-r--r-- | drivers/md/bcache/writeback.c | 12 | ||||
-rw-r--r-- | drivers/md/bcache/xattr.c | 32 |
10 files changed, 62 insertions, 49 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 5c3b0c15aab9..8db2f8c62e3a 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -2313,6 +2313,13 @@ do_init_next: bch_btree_init_next(iter->c, b, iter); struct btree_split_state { struct closure stack_cl; struct keylist parent_keys; + /* + * Enough room for btree_split's keys without realloc - btree node + * pointers never have crc/compression info, so we only need to acount + * for the pointers for three keys + */ + u64 inline_keys[(BKEY_U64s + + BKEY_EXTENT_PTRS_MAX) * 3]; struct btree_reserve *reserve; }; @@ -2492,9 +2499,9 @@ static void btree_split(struct btree *b, struct btree_iter *iter, bch_btree_set_root(c, n3); } else if (!parent) { - BUG_ON(state->parent_keys.start_keys_p != - state->parent_keys.inline_keys); - bch_keylist_init(&state->parent_keys); + bch_keylist_init(&state->parent_keys, + state->inline_keys, + ARRAY_SIZE(state->inline_keys)); /* Root filled up but didn't need to be split */ closure_sync(&state->stack_cl); @@ -2611,7 +2618,9 @@ int bch_btree_insert_node(struct btree *b, struct btree_split_state state; closure_init_stack(&state.stack_cl); - bch_keylist_init(&state.parent_keys); + bch_keylist_init(&state.parent_keys, + state.inline_keys, + ARRAY_SIZE(state.inline_keys)); state.reserve = reserve; if (replace) diff --git a/drivers/md/bcache/dirent.c b/drivers/md/bcache/dirent.c index 999538c71391..9f780b0f4e59 100644 --- a/drivers/md/bcache/dirent.c +++ b/drivers/md/bcache/dirent.c @@ -144,7 +144,7 @@ static int __bch_dirent_create(struct cache_set *c, u64 dir_inum, sizeof(u64)); int ret = -ENOENT; - bch_keylist_init(&keys); + bch_keylist_init(&keys, NULL, 0); if (bch_keylist_realloc(&keys, u64s)) return -ENOMEM; diff --git a/drivers/md/bcache/gc.c b/drivers/md/bcache/gc.c index fb335f89a68b..afdb8e92f8d2 100644 --- a/drivers/md/bcache/gc.c +++ b/drivers/md/bcache/gc.c @@ -368,7 +368,7 @@ static void bch_coalesce_nodes(struct btree *old_nodes[GC_MERGE_NODES], return; memset(new_nodes, 0, sizeof(new_nodes)); - bch_keylist_init(&keylist); + bch_keylist_init(&keylist, NULL, 0); closure_init_stack(&cl); /* Count keys that are not deleted */ diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c index 1cebe3376576..c264e4361ce9 100644 --- a/drivers/md/bcache/io.c +++ b/drivers/md/bcache/io.c @@ -608,7 +608,6 @@ void bch_write(struct closure *cl) op->insert_key.k.p.offset = bio_end_sector(op->bio); op->insert_key.k.size = bio_sectors(op->bio); - bch_keylist_init(&op->insert_keys); bio_get(op->bio); /* Don't call bch_next_delay() if rate is >= 1 GB/sec */ @@ -680,7 +679,9 @@ void bch_write_op_init(struct bch_write_op *op, struct cache_set *c, op->wp = wp; op->journal_seq = NULL; - bch_keylist_init(&op->insert_keys); + bch_keylist_init(&op->insert_keys, + op->inline_keys, + ARRAY_SIZE(op->inline_keys)); bkey_reassemble(&op->insert_key, insert_key); if (!bkey_val_u64s(&op->insert_key.k)) { diff --git a/drivers/md/bcache/io.h b/drivers/md/bcache/io.h index ef7122a591da..1d97fac2665c 100644 --- a/drivers/md/bcache/io.h +++ b/drivers/md/bcache/io.h @@ -59,6 +59,7 @@ struct bch_write_op { struct keylist insert_keys; BKEY_PADDED(insert_key); struct bch_replace_info replace_info; + u64 inline_keys[BKEY_EXTENT_MAX_U64s * 2]; }; enum bch_write_flags { diff --git a/drivers/md/bcache/keylist.c b/drivers/md/bcache/keylist.c index f6f7eabf9b0f..94412518bc1a 100644 --- a/drivers/md/bcache/keylist.c +++ b/drivers/md/bcache/keylist.c @@ -13,7 +13,7 @@ int bch_keylist_realloc_max(struct keylist *l, unsigned maxu64s) { size_t oldcap = bch_keylist_capacity(l); - size_t newsize = oldcap + needu64s; + size_t newsize = max(oldcap, BKEY_EXTENT_MAX_U64s) + needu64s; u64 *new_keys; if (bch_keylist_fits(l, needu64s)) @@ -78,8 +78,9 @@ int bch_keylist_realloc_max(struct keylist *l, l->bot_p = new_keys; } - if (l->start_keys_p != l->inline_keys) + if (l->has_buf) kfree(l->start_keys_p); + l->has_buf = true; l->start_keys_p = new_keys; l->end_keys_p = new_keys + newsize; @@ -129,7 +130,7 @@ void bch_scan_keylist_init(struct scan_keylist *kl, mutex_init(&kl->lock); kl->max_size = max_size; - bch_keylist_init(&kl->list); + bch_keylist_init(&kl->list, NULL, 0); /* * Order of initialization is tricky, and this makes sure that diff --git a/drivers/md/bcache/keylist.h b/drivers/md/bcache/keylist.h index 6e2867cc9f83..5e760003cb0a 100644 --- a/drivers/md/bcache/keylist.h +++ b/drivers/md/bcache/keylist.h @@ -3,10 +3,12 @@ #include "keylist_types.h" -static inline void bch_keylist_init(struct keylist *l) +static inline void bch_keylist_init(struct keylist *l, u64 *inline_keys, + size_t nr_inline_u64s) { - l->bot_p = l->top_p = l->start_keys_p = l->inline_keys; - l->end_keys_p = &l->inline_keys[KEYLIST_INLINE]; + l->bot_p = l->top_p = l->start_keys_p = inline_keys; + l->end_keys_p = l->start_keys_p + nr_inline_u64s; + l->has_buf = false; } static inline size_t bch_keylist_capacity(struct keylist *l) @@ -14,6 +16,11 @@ static inline size_t bch_keylist_capacity(struct keylist *l) return l->end_keys_p - l->start_keys_p; } +/* + * XXX: why are we using BKEY_EXTENT_MAX_U64s here? keylists aren't used just + * for extents, this doesn't make any sense + */ + static inline bool bch_keylist_fits(struct keylist *l, size_t u64s) { if (l->bot_p > l->top_p) @@ -59,10 +66,9 @@ static inline bool bch_keylist_empty(struct keylist *l) static inline void bch_keylist_free(struct keylist *l) { - if (l->start_keys_p != l->inline_keys) { + if (l->has_buf) kfree(l->start_keys_p); - bch_keylist_init(l); - } + memset(l, 0, sizeof(*l)); } /* diff --git a/drivers/md/bcache/keylist_types.h b/drivers/md/bcache/keylist_types.h index b48cc208472a..04cb866d36da 100644 --- a/drivers/md/bcache/keylist_types.h +++ b/drivers/md/bcache/keylist_types.h @@ -22,6 +22,8 @@ * full. */ +#define KEYLIST_MAX (1 << 18) + struct keylist { /* This is a pointer to the LSB (inline_keys until realloc'd) */ union { @@ -43,18 +45,7 @@ struct keylist { struct bkey_i *end_keys; u64 *end_keys_p; }; - /* Enough room for btree_split's keys without realloc */ -#define KEYLIST_INLINE roundup_pow_of_two(BKEY_EXTENT_MAX_U64s * 3) - /* Prevent key lists from growing too big */ - /* - * This should always be big enough to allow btree_gc_coalesce and - * btree_split to complete. - * The current value is the (current) size of a bucket, so it - * is far more than enough, as those two operations require only - * a handful of keys. - */ -#define KEYLIST_MAX (1 << 18) - u64 inline_keys[KEYLIST_INLINE]; + bool has_buf; }; /* diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 383745ef0c02..bd8ac8ea2d22 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -110,16 +110,14 @@ static void write_dirty_finish(struct closure *cl) mempool_free(bv->bv_page, &dc->writeback_page_pool); if (!io->error) { + BKEY_PADDED(k) tmp; int ret; - struct keylist keys; - bch_keylist_init(&keys); + bkey_copy(&tmp.k, &io->replace.key); + SET_EXTENT_CACHED(&bkey_i_to_extent(&tmp.k)->v, true); - bkey_copy(keys.top, &io->replace.key); - SET_EXTENT_CACHED(&bkey_i_to_extent(keys.top)->v, true); - bch_keylist_enqueue(&keys); - - ret = bch_btree_insert(dc->disk.c, BTREE_ID_EXTENTS, &keys, + ret = bch_btree_insert(dc->disk.c, BTREE_ID_EXTENTS, + &keylist_single(&tmp.k), &io->replace, NULL, NULL, 0); if (io->replace.successes == 0) trace_bcache_writeback_collision(&io->replace.key.k); diff --git a/drivers/md/bcache/xattr.c b/drivers/md/bcache/xattr.c index 404796ff8163..2f9f176609bc 100644 --- a/drivers/md/bcache/xattr.c +++ b/drivers/md/bcache/xattr.c @@ -186,7 +186,6 @@ int bch_xattr_set(struct inode *inode, const char *name, struct cache_set *c = inode->i_sb->s_fs_info; struct btree_iter iter; struct bkey_s_c k; - struct keylist keys; struct qstr qname = (struct qstr) QSTR_INIT((char *) name, strlen(name)); int ret = -EINVAL; @@ -226,9 +225,8 @@ int bch_xattr_set(struct inode *inode, const char *name, break; } - bch_keylist_init(&keys); - if (value) { + struct keylist keys; struct bkey_i_xattr *xattr; unsigned u64s = BKEY_U64s + DIV_ROUND_UP(sizeof(struct bch_xattr) + @@ -240,6 +238,8 @@ int bch_xattr_set(struct inode *inode, const char *name, break; } + bch_keylist_init(&keys, NULL, 0); + if (bch_keylist_realloc(&keys, u64s)) { ret = -ENOMEM; break; @@ -255,20 +255,26 @@ int bch_xattr_set(struct inode *inode, const char *name, memcpy(xattr_val(&xattr->v), value, size); BUG_ON(xattr_cmp(&xattr->v, type, &qname)); + + bch_keylist_enqueue(&keys); + + ret = bch_btree_insert_at(&iter, &keys, NULL, + &ei->journal_seq, + insert_flags); + bch_keylist_free(&keys); } else { + struct bkey_i whiteout; /* removing */ - bkey_init(&keys.top->k); - keys.top->k.type = BCH_XATTR_WHITEOUT; - keys.top->k.p = k.k->p; + bkey_init(&whiteout.k); + whiteout.k.type = BCH_XATTR_WHITEOUT; + whiteout.k.p = k.k->p; + + ret = bch_btree_insert_at(&iter, + &keylist_single(&whiteout), + NULL, &ei->journal_seq, + insert_flags); } - bch_keylist_enqueue(&keys); - - ret = bch_btree_insert_at(&iter, &keys, NULL, - &ei->journal_seq, - insert_flags); - bch_keylist_free(&keys); - if (ret != -EINTR && ret != -EAGAIN) break; } |