summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-11-21 17:23:57 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:41:06 -0900
commit8af7fd4e0b0fcd8fab5bb70bd33ae9270fd8ff20 (patch)
treee59ade29a382e0e18be649622b137d8c9d3bc475
parent069a5ecc2da9edc7e8dd24499c07df03ea182e63 (diff)
bcache: btree insert path refactoring
-rw-r--r--drivers/md/bcache/btree_update.c62
-rw-r--r--drivers/md/bcache/btree_update.h19
-rw-r--r--drivers/md/bcache/extents.c62
-rw-r--r--drivers/md/bcache/extents.h8
4 files changed, 69 insertions, 82 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index 0224e4176aa5..cdb11a8734d0 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -734,17 +734,18 @@ static void btree_node_flush1(struct journal *j, struct journal_entry_pin *pin)
return __btree_node_flush(j, pin, 1);
}
-void bch_btree_journal_key(struct btree_iter *iter,
- struct bkey_i *insert,
- struct journal_res *res)
+void bch_btree_journal_key(struct btree_insert *trans,
+ struct btree_iter *iter,
+ struct bkey_i *insert)
{
- struct cache_set *c = iter->c;
+ struct cache_set *c = trans->c;
struct journal *j = &c->journal;
struct btree *b = iter->nodes[0];
struct btree_write *w = btree_current_write(b);
EBUG_ON(iter->level || b->level);
- EBUG_ON(!res->ref && test_bit(JOURNAL_REPLAY_DONE, &j->flags));
+ EBUG_ON(!trans->journal_res.ref &&
+ test_bit(JOURNAL_REPLAY_DONE, &j->flags));
if (!journal_pin_active(&w->journal))
bch_journal_pin_add(j, &w->journal,
@@ -752,16 +753,39 @@ void bch_btree_journal_key(struct btree_iter *iter,
? btree_node_flush0
: btree_node_flush1);
- if (res->ref) {
- bch_journal_add_keys(j, res, b->btree_id, insert);
- btree_bset_last(b)->journal_seq =
- cpu_to_le64(bch_journal_res_seq(j, res));
+ if (trans->journal_res.ref) {
+ u64 seq = bch_journal_res_seq(j, &trans->journal_res);
+
+ bch_journal_add_keys(j, &trans->journal_res,
+ b->btree_id, insert);
+
+ if (trans->journal_seq)
+ *trans->journal_seq = seq;
+ btree_bset_last(b)->journal_seq = cpu_to_le64(seq);
}
if (!btree_node_dirty(b))
set_btree_node_dirty(b);
}
+static enum btree_insert_ret
+bch_insert_fixup_key(struct btree_insert *trans,
+ struct btree_insert_entry *insert)
+{
+ struct btree_iter *iter = insert->iter;
+
+ BUG_ON(iter->level);
+
+ bch_btree_journal_key(trans, iter, insert->k);
+ bch_btree_bset_insert_key(iter,
+ iter->nodes[0],
+ &iter->node_iters[0],
+ insert->k);
+
+ trans->did_work = true;
+ return BTREE_INSERT_OK;
+}
+
static void verify_keys_sorted(struct keylist *l)
{
#ifdef CONFIG_BCACHE_DEBUG
@@ -1721,8 +1745,7 @@ out:
*/
static enum btree_insert_ret
btree_insert_key(struct btree_insert *trans,
- struct btree_insert_entry *insert,
- struct journal_res *res)
+ struct btree_insert_entry *insert)
{
struct cache_set *c = trans->c;
struct btree_iter *iter = insert->iter;
@@ -1733,8 +1756,8 @@ btree_insert_key(struct btree_insert *trans,
int live_u64s_added, u64s_added;
ret = !btree_node_is_extents(b)
- ? bch_insert_fixup_key(trans, insert, res)
- : bch_insert_fixup_extent(trans, insert, res);
+ ? bch_insert_fixup_key(trans, insert)
+ : bch_insert_fixup_extent(trans, insert);
live_u64s_added = (int) b->keys.nr.live_u64s - old_live_u64s;
u64s_added = (int) le16_to_cpu(btree_bset_last(b)->u64s) - old_u64s;
@@ -1805,10 +1828,9 @@ static int btree_trans_entry_cmp(const void *_l, const void *_r)
* -EROFS: cache set read only
* -EIO: journal or btree node IO error
*/
-int __bch_btree_insert_at(struct btree_insert *trans, u64 *journal_seq)
+int __bch_btree_insert_at(struct btree_insert *trans)
{
struct cache_set *c = trans->c;
- struct journal_res res = { 0, 0 };
struct btree_insert_entry *i;
struct btree_iter *split = NULL;
bool cycle_gc_lock = false;
@@ -1837,8 +1859,12 @@ retry:
if (!i->done)
u64s += jset_u64s(i->k->k.u64s);
+ memset(&trans->journal_res, 0, sizeof(trans->journal_res));
+
ret = !(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)
- ? bch_journal_res_get(&c->journal, &res, u64s, u64s)
+ ? bch_journal_res_get(&c->journal,
+ &trans->journal_res,
+ u64s, u64s)
: 0;
if (ret)
goto err;
@@ -1869,7 +1895,7 @@ retry:
if (i->done)
continue;
- switch (btree_insert_key(trans, i, &res)) {
+ switch (btree_insert_key(trans, i)) {
case BTREE_INSERT_OK:
i->done = true;
break;
@@ -1899,7 +1925,7 @@ retry:
}
unlock:
multi_unlock_write(trans);
- bch_journal_res_put(&c->journal, &res, journal_seq);
+ bch_journal_res_put(&c->journal, &trans->journal_res, NULL);
if (split)
goto split;
diff --git a/drivers/md/bcache/btree_update.h b/drivers/md/bcache/btree_update.h
index d42b1b66e166..4311dd17f82a 100644
--- a/drivers/md/bcache/btree_update.h
+++ b/drivers/md/bcache/btree_update.h
@@ -168,8 +168,8 @@ int bch_btree_root_alloc(struct cache_set *, enum btree_id, struct closure *);
void bch_btree_bset_insert_key(struct btree_iter *, struct btree *,
struct btree_node_iter *, struct bkey_i *);
-void bch_btree_journal_key(struct btree_iter *, struct bkey_i *,
- struct journal_res *);
+void bch_btree_journal_key(struct btree_insert *trans, struct btree_iter *,
+ struct bkey_i *);
static inline void *write_block(struct btree *b)
{
@@ -227,6 +227,8 @@ void bch_btree_insert_node(struct btree *, struct btree_iter *,
struct btree_insert {
struct cache_set *c;
struct disk_reservation *disk_res;
+ struct journal_res journal_res;
+ u64 *journal_seq;
struct extent_insert_hook *hook;
unsigned flags;
bool did_work;
@@ -243,7 +245,7 @@ struct btree_insert {
} *entries;
};
-int __bch_btree_insert_at(struct btree_insert *, u64 *);
+int __bch_btree_insert_at(struct btree_insert *);
#define _TENTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
@@ -274,13 +276,13 @@ int __bch_btree_insert_at(struct btree_insert *, u64 *);
__bch_btree_insert_at(&(struct btree_insert) { \
.c = (_c), \
.disk_res = (_disk_res), \
+ .journal_seq = (_journal_seq), \
.hook = (_hook), \
.flags = (_flags), \
.nr = COUNT_ARGS(__VA_ARGS__), \
.entries = (struct btree_insert_entry[]) { \
__VA_ARGS__ \
- }}, \
- _journal_seq)
+ }})
/*
* Don't drop/retake locks: instead return -EINTR if need to upgrade to intent
@@ -305,8 +307,7 @@ int bch_btree_insert_list_at(struct btree_iter *, struct keylist *,
struct extent_insert_hook *, u64 *, unsigned);
static inline bool journal_res_insert_fits(struct btree_insert *trans,
- struct btree_insert_entry *insert,
- struct journal_res *res)
+ struct btree_insert_entry *insert)
{
unsigned u64s = 0;
struct btree_insert_entry *i;
@@ -315,13 +316,13 @@ static inline bool journal_res_insert_fits(struct btree_insert *trans,
* If we didn't get a journal reservation, we're in journal replay and
* we're not journalling updates:
*/
- if (!res->ref)
+ if (!trans->journal_res.ref)
return true;
for (i = insert; i < trans->entries + trans->nr; i++)
u64s += jset_u64s(i->k->k.u64s);
- return u64s <= res->u64s;
+ return u64s <= trans->journal_res.u64s;
}
int bch_btree_insert_check_key(struct btree_iter *, struct bkey_i *);
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index 33687fc82ac4..5419b1f09738 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -107,27 +107,6 @@ struct btree_nr_keys bch_key_sort_fix_overlapping(struct bset *dst,
return nr;
}
-/* This returns true if insert should be inserted, false otherwise */
-
-enum btree_insert_ret
-bch_insert_fixup_key(struct btree_insert *trans,
- struct btree_insert_entry *insert,
- struct journal_res *res)
-{
- struct btree_iter *iter = insert->iter;
-
- BUG_ON(iter->level);
-
- bch_btree_journal_key(iter, insert->k, res);
- bch_btree_bset_insert_key(iter,
- iter->nodes[0],
- &iter->node_iters[0],
- insert->k);
-
- trans->did_work = true;
- return BTREE_INSERT_OK;
-}
-
/* Common among btree and extent ptrs */
bool bch_extent_has_device(struct bkey_s_c_extent e, unsigned dev)
@@ -1066,7 +1045,6 @@ static bool bch_extent_merge_inline(struct cache_set *,
static enum btree_insert_ret extent_insert_should_stop(struct btree_insert *trans,
struct btree_insert_entry *insert,
- struct journal_res *res,
u64 start_time,
unsigned nr_done)
{
@@ -1086,7 +1064,7 @@ static enum btree_insert_ret extent_insert_should_stop(struct btree_insert *tran
*/
if (!bch_btree_node_insert_fits(trans->c, b, insert->k->k.u64s))
return BTREE_INSERT_BTREE_NODE_FULL;
- else if (!journal_res_insert_fits(trans, insert, res))
+ else if (!journal_res_insert_fits(trans, insert))
return BTREE_INSERT_JOURNAL_RES_FULL; /* XXX worth tracing */
else if (nr_done > 10 &&
time_after64(local_clock(), start_time +
@@ -1140,19 +1118,9 @@ drop_deleted_keys:
bch_btree_node_iter_fix(iter, b, node_iter, t, where, clobber_u64s, 0);
}
-static void extent_insert_and_journal(struct cache_set *c, struct btree_iter *iter,
- struct bkey_i *insert,
- struct journal_res *res)
-{
- bch_btree_journal_key(iter, insert, res);
-
- extent_bset_insert(c, iter, insert);
-}
-
static void extent_insert_committed(struct btree_insert *trans,
struct btree_insert_entry *insert,
struct bpos committed_pos,
- struct journal_res *res,
struct bucket_stats_cache_set *stats)
{
struct cache_set *c = trans->c;
@@ -1188,7 +1156,9 @@ static void extent_insert_committed(struct btree_insert *trans,
bkey_debugcheck(c, iter->nodes[iter->level],
bkey_i_to_s_c(&split.k));
- extent_insert_and_journal(c, iter, &split.k, res);
+ bch_btree_journal_key(trans, iter, &split.k);
+
+ extent_bset_insert(c, iter, &split.k);
bch_btree_iter_set_pos_same_leaf(iter, committed_pos);
@@ -1202,7 +1172,6 @@ __extent_insert_advance_pos(struct btree_insert *trans,
struct bpos *committed_pos,
struct bpos next_pos,
struct bkey_s_c k,
- struct journal_res *res,
struct bucket_stats_cache_set *stats)
{
struct extent_insert_hook *hook = trans->hook;
@@ -1223,8 +1192,7 @@ __extent_insert_advance_pos(struct btree_insert *trans,
case BTREE_HOOK_DO_INSERT:
break;
case BTREE_HOOK_NO_INSERT:
- extent_insert_committed(trans, insert, *committed_pos,
- res, stats);
+ extent_insert_committed(trans, insert, *committed_pos, stats);
bch_cut_subtract_front(insert->iter, next_pos,
bkey_i_to_s(insert->k), stats);
@@ -1247,7 +1215,6 @@ extent_insert_advance_pos(struct btree_insert *trans,
struct btree_insert_entry *insert,
struct bpos *committed_pos,
struct bkey_s_c k,
- struct journal_res *res,
struct bucket_stats_cache_set *stats)
{
struct btree *b = insert->iter->nodes[0];
@@ -1263,7 +1230,7 @@ extent_insert_advance_pos(struct btree_insert *trans,
committed_pos,
bkey_start_pos(k.k),
bkey_s_c_null,
- res, stats)) {
+ stats)) {
case BTREE_HOOK_DO_INSERT:
break;
case BTREE_HOOK_NO_INSERT:
@@ -1285,7 +1252,7 @@ extent_insert_advance_pos(struct btree_insert *trans,
return BTREE_HOOK_DO_INSERT;
return __extent_insert_advance_pos(trans, insert, committed_pos,
- next_pos, k, res, stats);
+ next_pos, k, stats);
}
/**
@@ -1329,8 +1296,7 @@ extent_insert_advance_pos(struct btree_insert *trans,
*/
enum btree_insert_ret
bch_insert_fixup_extent(struct btree_insert *trans,
- struct btree_insert_entry *insert,
- struct journal_res *res)
+ struct btree_insert_entry *insert)
{
struct cache_set *c = trans->c;
struct btree_iter *iter = insert->iter;
@@ -1362,7 +1328,7 @@ bch_insert_fixup_extent(struct btree_insert *trans,
insert->k->k.size, &stats);
while (bkey_cmp(committed_pos, insert->k->k.p) < 0 &&
- (ret = extent_insert_should_stop(trans, insert, res,
+ (ret = extent_insert_should_stop(trans, insert,
start_time, nr_done)) == BTREE_INSERT_OK &&
(_k = bch_btree_node_iter_peek_all(node_iter, &b->keys))) {
struct bset_tree *t = bch_bkey_to_bset(&b->keys, _k);
@@ -1409,7 +1375,7 @@ bch_insert_fixup_extent(struct btree_insert *trans,
if (k.k->size)
switch (extent_insert_advance_pos(trans, insert,
&committed_pos,
- k.s_c, res, &stats)) {
+ k.s_c, &stats)) {
case BTREE_HOOK_DO_INSERT:
break;
case BTREE_HOOK_NO_INSERT:
@@ -1468,13 +1434,13 @@ bch_insert_fixup_extent(struct btree_insert *trans,
if (extent_insert_advance_pos(trans, insert,
&committed_pos,
- k.s_c, res, &stats) ==
+ k.s_c, &stats) ==
BTREE_HOOK_RESTART_TRANS) {
ret = BTREE_INSERT_NEED_TRAVERSE;
goto stop;
}
extent_insert_committed(trans, insert, committed_pos,
- res, &stats);
+ &stats);
/*
* We split and inserted upto at k.k->p - that
* has to coincide with iter->pos, so that we
@@ -1526,11 +1492,11 @@ bch_insert_fixup_extent(struct btree_insert *trans,
if (bkey_cmp(committed_pos, insert->k->k.p) < 0 &&
ret == BTREE_INSERT_OK &&
extent_insert_advance_pos(trans, insert, &committed_pos,
- bkey_s_c_null, res,
+ bkey_s_c_null,
&stats) == BTREE_HOOK_RESTART_TRANS)
ret = BTREE_INSERT_NEED_TRAVERSE;
stop:
- extent_insert_committed(trans, insert, committed_pos, res, &stats);
+ extent_insert_committed(trans, insert, committed_pos, &stats);
/*
* Subtract any remaining sectors from @insert, if we bailed out early
* and didn't fully insert @insert:
diff --git a/drivers/md/bcache/extents.h b/drivers/md/bcache/extents.h
index ccfb0d165401..869a16523b52 100644
--- a/drivers/md/bcache/extents.h
+++ b/drivers/md/bcache/extents.h
@@ -19,11 +19,6 @@ struct btree_nr_keys bch_extent_sort_fix_overlapping(struct cache_set *c,
struct btree_keys *,
struct btree_node_iter *);
-enum btree_insert_ret
-bch_insert_fixup_key(struct btree_insert *,
- struct btree_insert_entry *,
- struct journal_res *);
-
extern const struct bkey_ops bch_bkey_btree_ops;
extern const struct bkey_ops bch_bkey_extent_ops;
@@ -55,8 +50,7 @@ bch_extent_cmpxchg(struct extent_insert_hook *, struct bpos, struct bpos,
enum btree_insert_ret
bch_insert_fixup_extent(struct btree_insert *,
- struct btree_insert_entry *,
- struct journal_res *);
+ struct btree_insert_entry *);
bool bch_extent_normalize(struct cache_set *, struct bkey_s);