Commit 59158fde authored by Kent Overstreet's avatar Kent Overstreet

bcache: Add bch_btree_keys_u64s_remaining()

Helper function to explicitly check how much space is free in a btree node
Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
parent a85e968e
...@@ -260,6 +260,21 @@ static inline bool btree_keys_expensive_checks(struct btree_keys *b) ...@@ -260,6 +260,21 @@ static inline bool btree_keys_expensive_checks(struct btree_keys *b)
#define set_blocks(i, block_bytes) \ #define set_blocks(i, block_bytes) \
__set_blocks(i, (i)->keys, block_bytes) __set_blocks(i, (i)->keys, block_bytes)
static inline size_t bch_btree_keys_u64s_remaining(struct btree_keys *b)
{
struct bset_tree *t = bset_tree_last(b);
BUG_ON((PAGE_SIZE << b->page_order) <
(bset_byte_offset(b, t->data) + set_bytes(t->data)));
if (!b->last_set_unwritten)
return 0;
return ((PAGE_SIZE << b->page_order) -
(bset_byte_offset(b, t->data) + set_bytes(t->data))) /
sizeof(u64);
}
static inline struct bset *bset_next_set(struct btree_keys *b, static inline struct bset *bset_next_set(struct btree_keys *b,
unsigned block_bytes) unsigned block_bytes)
{ {
......
...@@ -179,14 +179,6 @@ static inline struct bset *write_block(struct btree *b) ...@@ -179,14 +179,6 @@ static inline struct bset *write_block(struct btree *b)
return ((void *) btree_bset_first(b)) + b->written * block_bytes(b->c); return ((void *) btree_bset_first(b)) + b->written * block_bytes(b->c);
} }
static inline bool should_split(struct btree *b)
{
struct bset *i = write_block(b);
return b->written >= btree_blocks(b) ||
(b->written + __set_blocks(i, i->keys + 15, block_bytes(b->c))
> btree_blocks(b));
}
/* Btree key manipulation */ /* Btree key manipulation */
void bkey_put(struct cache_set *c, struct bkey *k) void bkey_put(struct cache_set *c, struct bkey *k)
...@@ -2026,6 +2018,19 @@ copy: bkey_copy(m, k); ...@@ -2026,6 +2018,19 @@ copy: bkey_copy(m, k);
return true; return true;
} }
static size_t insert_u64s_remaining(struct btree *b)
{
ssize_t ret = bch_btree_keys_u64s_remaining(&b->keys);
/*
* Might land in the middle of an existing extent and have to split it
*/
if (b->keys.ops->is_extents)
ret -= KEY_MAX_U64S;
return max(ret, 0L);
}
static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op, static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op,
struct keylist *insert_keys, struct keylist *insert_keys,
struct bkey *replace_key) struct bkey *replace_key)
...@@ -2034,12 +2039,9 @@ static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op, ...@@ -2034,12 +2039,9 @@ static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op,
int oldsize = bch_count_data(b); int oldsize = bch_count_data(b);
while (!bch_keylist_empty(insert_keys)) { while (!bch_keylist_empty(insert_keys)) {
struct bset *i = write_block(b);
struct bkey *k = insert_keys->keys; struct bkey *k = insert_keys->keys;
if (b->written + if (bkey_u64s(k) > insert_u64s_remaining(b))
__set_blocks(i, i->keys + bkey_u64s(k),
block_bytes(b->c)) > btree_blocks(b))
break; break;
if (bkey_cmp(k, &b->key) <= 0) { if (bkey_cmp(k, &b->key) <= 0) {
...@@ -2203,7 +2205,7 @@ static int bch_btree_insert_node(struct btree *b, struct btree_op *op, ...@@ -2203,7 +2205,7 @@ static int bch_btree_insert_node(struct btree *b, struct btree_op *op,
{ {
BUG_ON(b->level && replace_key); BUG_ON(b->level && replace_key);
if (should_split(b)) { if (bch_keylist_nkeys(insert_keys) > insert_u64s_remaining(b)) {
if (current->bio_list) { if (current->bio_list) {
op->lock = b->c->root->level + 1; op->lock = b->c->root->level + 1;
return -EAGAIN; return -EAGAIN;
......
...@@ -39,6 +39,7 @@ static inline void SET_##name(struct bkey *k, unsigned i, __u64 v) \ ...@@ -39,6 +39,7 @@ static inline void SET_##name(struct bkey *k, unsigned i, __u64 v) \
} }
#define KEY_SIZE_BITS 16 #define KEY_SIZE_BITS 16
#define KEY_MAX_U64S 8
KEY_FIELD(KEY_PTRS, high, 60, 3) KEY_FIELD(KEY_PTRS, high, 60, 3)
KEY_FIELD(HEADER_SIZE, high, 58, 2) KEY_FIELD(HEADER_SIZE, high, 58, 2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment