diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-11-21 17:23:57 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-18 21:41:06 -0900 |
commit | 8af7fd4e0b0fcd8fab5bb70bd33ae9270fd8ff20 (patch) | |
tree | e59ade29a382e0e18be649622b137d8c9d3bc475 | |
parent | 069a5ecc2da9edc7e8dd24499c07df03ea182e63 (diff) |
bcache: btree insert path refactoring
-rw-r--r-- | drivers/md/bcache/btree_update.c | 62 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.h | 19 | ||||
-rw-r--r-- | drivers/md/bcache/extents.c | 62 | ||||
-rw-r--r-- | drivers/md/bcache/extents.h | 8 |
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); |