diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-08-05 22:23:16 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-08-05 22:23:16 -0800 |
commit | 885262cd16cc8a0c312f914e25227954cd964c8d (patch) | |
tree | 7a6b1c8350dc04deeb16a83b5e1349f2f556993d | |
parent | 435056ec0bed1984039ff9c10507e599ffee402c (diff) |
bcache: more btree insert path refactoring
-rw-r--r-- | drivers/md/bcache/btree_update.c | 37 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.h | 20 | ||||
-rw-r--r-- | drivers/md/bcache/extents.c | 58 | ||||
-rw-r--r-- | drivers/md/bcache/extents.h | 4 |
4 files changed, 51 insertions, 68 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index e87df3734882..251d2f6e7d65 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -1499,10 +1499,7 @@ out_get_locks: static enum btree_insert_ret btree_insert_key(struct btree_insert *trans, struct btree_insert_entry *insert, - struct disk_reservation *disk_res, - struct extent_insert_hook *hook, - struct journal_res *res, - unsigned flags) + struct journal_res *res) { struct btree_iter *iter = insert->iter; struct btree *b = iter->nodes[0]; @@ -1510,8 +1507,7 @@ btree_insert_key(struct btree_insert *trans, ret = !b->keys.ops->is_extents ? bch_insert_fixup_key(trans, insert, res) - : bch_insert_fixup_extent(trans, insert, disk_res, - hook, res, flags); + : bch_insert_fixup_extent(trans, insert, res); trace_bcache_btree_insert_key(b, insert->k); return ret; @@ -1570,10 +1566,7 @@ 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, - struct disk_reservation *disk_res, - struct extent_insert_hook *hook, - u64 *journal_seq, unsigned flags) +int __bch_btree_insert_at(struct btree_insert *trans, u64 *journal_seq) { struct cache_set *c = trans->c; struct journal_res res = { 0, 0 }; @@ -1588,9 +1581,7 @@ int __bch_btree_insert_at(struct btree_insert *trans, trans_for_each_entry(trans, i) { EBUG_ON(i->iter->level); EBUG_ON(bkey_cmp(bkey_start_pos(&i->k->k), i->iter->pos)); - i->done = false; } - trans->did_work = false; sort(trans->entries, trans->nr, sizeof(trans->entries[0]), btree_trans_entry_cmp, NULL); @@ -1606,6 +1597,7 @@ int __bch_btree_insert_at(struct btree_insert *trans, } } retry: + trans->did_work = false; u64s = 0; trans_for_each_entry(trans, i) if (!i->done) @@ -1628,8 +1620,10 @@ retry: if (!i->done) { u64s += i->k->k.u64s; if (!bch_btree_node_insert_fits(c, - i->iter->nodes[0], u64s)) - goto unlock_split; + i->iter->nodes[0], u64s)) { + split = i->iter; + goto unlock; + } } } @@ -1640,8 +1634,7 @@ retry: if (i->done) continue; - switch (btree_insert_key(trans, i, disk_res, - hook, &res, flags)) { + switch (btree_insert_key(trans, i, &res)) { case BTREE_INSERT_OK: i->done = true; break; @@ -1663,7 +1656,7 @@ retry: if (!trans->did_work && (ret || split)) break; } - +unlock: multi_unlock_write(trans); bch_journal_res_put(&c->journal, &res, journal_seq); @@ -1678,17 +1671,13 @@ retry: out: percpu_ref_put(&c->writes); return ret; -unlock_split: - split = i->iter; - multi_unlock_write(trans); +split: /* * have to drop journal res before splitting, because splitting means * allocating new btree nodes, and holding a journal reservation * potentially blocks the allocator: */ - bch_journal_res_put(&c->journal, &res, journal_seq); -split: - ret = bch_btree_split_leaf(split, flags, &cl); + ret = bch_btree_split_leaf(split, trans->flags, &cl); if (ret) goto err; @@ -1719,7 +1708,7 @@ err: * BTREE_INSERT_ATOMIC doesn't mean anything w.r.t. journal * reservations: */ - if (ret == -EINTR && !(flags & BTREE_INSERT_ATOMIC)) { + if (ret == -EINTR && !(trans->flags & BTREE_INSERT_ATOMIC)) { trans_for_each_entry(trans, i) { ret = bch_btree_iter_traverse(i->iter); if (ret) diff --git a/drivers/md/bcache/btree_update.h b/drivers/md/bcache/btree_update.h index 7b22451110e5..f5250dee951d 100644 --- a/drivers/md/bcache/btree_update.h +++ b/drivers/md/bcache/btree_update.h @@ -191,9 +191,12 @@ void bch_btree_insert_node(struct btree *, struct btree_iter *, struct btree_insert { struct cache_set *c; - + struct disk_reservation *disk_res; + struct extent_insert_hook *hook; + unsigned flags; bool did_work; - unsigned nr; + + unsigned short nr; struct btree_insert_entry { struct btree_iter *iter; struct bkey_i *k; @@ -205,10 +208,7 @@ struct btree_insert { } *entries; }; -int __bch_btree_insert_at(struct btree_insert *, - struct disk_reservation *, - struct extent_insert_hook *, - u64 *, unsigned); +int __bch_btree_insert_at(struct btree_insert *, u64 *); #define _TENTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N @@ -237,13 +237,15 @@ int __bch_btree_insert_at(struct btree_insert *, #define bch_btree_insert_at(_c, _disk_res, _hook, \ _journal_seq, _flags, ...) \ __bch_btree_insert_at(&(struct btree_insert) { \ - .c = _c, \ - .did_work = false, \ + .c = (_c), \ + .disk_res = (_disk_res), \ + .hook = (_hook), \ + .flags = (_flags), \ .nr = COUNT_ARGS(__VA_ARGS__), \ .entries = (struct btree_insert_entry[]) { \ __VA_ARGS__ \ }}, \ - _disk_res, _hook, _journal_seq, _flags) + _journal_seq) /* * Don't drop/retake locks: instead return -EINTR if need to upgrade to intent diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c index c6b0a709f0cb..ed537159f5e6 100644 --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c @@ -1058,7 +1058,7 @@ static void extent_do_insert(struct btree_iter *iter, struct bkey_i *insert, static void extent_insert_committed(struct btree_insert *trans, struct btree_insert_entry *insert, struct bpos committed_pos, - struct journal_res *res, unsigned flags, + struct journal_res *res, struct bucket_stats_cache_set *stats) { @@ -1072,7 +1072,7 @@ static void extent_insert_committed(struct btree_insert *trans, EBUG_ON(bkey_deleted(&insert->k->k) || !insert->k->k.size); split = bch_key_split(committed_pos, insert->k); - extent_do_insert(insert->iter, split, res, flags, stats); + extent_do_insert(insert->iter, split, res, trans->flags, stats); bch_btree_iter_set_pos_same_leaf(insert->iter, committed_pos); @@ -1083,13 +1083,13 @@ static void extent_insert_committed(struct btree_insert *trans, static enum extent_insert_hook_ret __extent_insert_advance_pos(struct btree_insert *trans, struct btree_insert_entry *insert, - struct extent_insert_hook *hook, struct bpos *committed_pos, struct bpos next_pos, struct bkey_s_c k, - struct journal_res *res, unsigned flags, + struct journal_res *res, struct bucket_stats_cache_set *stats) { + struct extent_insert_hook *hook = trans->hook; enum extent_insert_hook_ret ret; if (k.k && k.k->size && @@ -1108,7 +1108,7 @@ __extent_insert_advance_pos(struct btree_insert *trans, break; case BTREE_HOOK_NO_INSERT: extent_insert_committed(trans, insert, *committed_pos, - res, flags, stats); + res, stats); __bch_cut_front(next_pos, bkey_i_to_s(insert->k)); bch_btree_iter_set_pos_same_leaf(insert->iter, next_pos); @@ -1128,10 +1128,9 @@ __extent_insert_advance_pos(struct btree_insert *trans, static enum extent_insert_hook_ret extent_insert_advance_pos(struct btree_insert *trans, struct btree_insert_entry *insert, - struct extent_insert_hook *hook, struct bpos *committed_pos, struct bkey_s_c k, - struct journal_res *res, unsigned flags, + struct journal_res *res, struct bucket_stats_cache_set *stats) { struct btree *b = insert->iter->nodes[0]; @@ -1143,11 +1142,11 @@ extent_insert_advance_pos(struct btree_insert *trans, bool have_uncommitted = bkey_cmp(*committed_pos, bkey_start_pos(&insert->k->k)) > 0; - switch (__extent_insert_advance_pos(trans, insert, hook, + switch (__extent_insert_advance_pos(trans, insert, committed_pos, bkey_start_pos(k.k), bkey_s_c_null, - res, flags, stats)) { + res, stats)) { case BTREE_HOOK_DO_INSERT: break; case BTREE_HOOK_NO_INSERT: @@ -1168,9 +1167,8 @@ extent_insert_advance_pos(struct btree_insert *trans, if (!bkey_cmp(*committed_pos, next_pos)) return BTREE_HOOK_DO_INSERT; - return __extent_insert_advance_pos(trans, insert, hook, - committed_pos, next_pos, - k, res, flags, stats); + return __extent_insert_advance_pos(trans, insert, committed_pos, + next_pos, k, res, stats); } /** @@ -1215,10 +1213,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 disk_reservation *disk_res, - struct extent_insert_hook *hook, - struct journal_res *res, - unsigned flags) + struct journal_res *res) { struct cache_set *c = trans->c; struct btree_iter *iter = insert->iter; @@ -1261,14 +1256,14 @@ bch_insert_fixup_extent(struct btree_insert *trans, if (k.k->size && overlap == BCH_EXTENT_OVERLAP_MIDDLE) { unsigned sectors = bkey_extent_is_compressed(c, k.s_c); - int res_flags = 0; + int flags = 0; - if (flags & BTREE_INSERT_NOFAIL) - res_flags |= BCH_DISK_RESERVATION_NOFAIL; + if (trans->flags & BTREE_INSERT_NOFAIL) + flags |= BCH_DISK_RESERVATION_NOFAIL; if (sectors && - bch_disk_reservation_add(c, disk_res, sectors, - res_flags)) { + bch_disk_reservation_add(c, trans->disk_res, + sectors, flags)) { ret = BTREE_INSERT_ENOSPC; goto stop; } @@ -1280,10 +1275,9 @@ bch_insert_fixup_extent(struct btree_insert *trans, * overlaps with @k: */ if (k.k->size) - switch (extent_insert_advance_pos(trans, insert, hook, + switch (extent_insert_advance_pos(trans, insert, &committed_pos, - k.s_c, res, flags, - &stats)) { + k.s_c, res, &stats)) { case BTREE_HOOK_DO_INSERT: break; case BTREE_HOOK_NO_INSERT: @@ -1339,15 +1333,14 @@ bch_insert_fixup_extent(struct btree_insert *trans, extent_save(&b->keys, node_iter, _k, k.k); if (extent_insert_advance_pos(trans, insert, - hook, &committed_pos, - k.s_c, res, flags, - &stats) == + &committed_pos, + k.s_c, res, &stats) == BTREE_HOOK_RESTART_TRANS) { ret = BTREE_INSERT_NEED_TRAVERSE; goto stop; } extent_insert_committed(trans, insert, committed_pos, - res, flags, &stats); + res, &stats); /* * We split and inserted upto at k.k->p - that * has to coincide with iter->pos, so that we @@ -1395,14 +1388,15 @@ 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, hook, &committed_pos, - bkey_s_c_null, res, flags, + extent_insert_advance_pos(trans, insert, &committed_pos, + bkey_s_c_null, res, &stats) == BTREE_HOOK_RESTART_TRANS) ret = BTREE_INSERT_NEED_TRAVERSE; stop: - extent_insert_committed(trans, insert, committed_pos, res, flags, &stats); + extent_insert_committed(trans, insert, committed_pos, res, &stats); - bch_cache_set_stats_apply(c, &stats, disk_res, gc_pos_btree_node(b)); + bch_cache_set_stats_apply(c, &stats, trans->disk_res, + gc_pos_btree_node(b)); EBUG_ON(bkey_cmp(iter->pos, bkey_start_pos(&insert->k->k))); EBUG_ON(bkey_cmp(iter->pos, committed_pos)); diff --git a/drivers/md/bcache/extents.h b/drivers/md/bcache/extents.h index f7c9585af9d7..91f65333176a 100644 --- a/drivers/md/bcache/extents.h +++ b/drivers/md/bcache/extents.h @@ -58,9 +58,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 disk_reservation *, - struct extent_insert_hook *, - struct journal_res *, unsigned); + struct journal_res *); void bch_extent_drop_stale(struct cache_set *c, struct bkey_s_extent); bool bch_extent_normalize(struct cache_set *, struct bkey_s); |