summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-04-07 07:20:07 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:39:00 -0900
commit3f7f1f1e782a41bf013311204aad9bed04460b2e (patch)
treec8ea2025589a7998ab4eb9af75ba5da84b122216
parentf89da52d37ee356bd095635d13fef85806f1e314 (diff)
bcache: Simplify reservations for extents
-rw-r--r--drivers/md/bcache/btree_update.c3
-rw-r--r--drivers/md/bcache/btree_update.h5
-rw-r--r--drivers/md/bcache/extents.c27
-rw-r--r--drivers/md/bcache/journal.h15
4 files changed, 25 insertions, 25 deletions
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index 20aeaa9193fc..215be17b62b9 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -1581,8 +1581,7 @@ retry:
u64s = 0;
for (i = m; i < m + nr; i++)
if (!i->done)
- u64s += journal_res_u64s_required(i->k,
- i->iter->is_extents);
+ u64s += jset_u64s(i->k->k.u64s);
ret = test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags)
? bch_journal_res_get(&c->journal, &res, u64s, u64s)
diff --git a/drivers/md/bcache/btree_update.h b/drivers/md/bcache/btree_update.h
index c64c88d4bb7f..1d459cf475e8 100644
--- a/drivers/md/bcache/btree_update.h
+++ b/drivers/md/bcache/btree_update.h
@@ -204,10 +204,7 @@ static inline bool bch_btree_node_insert_fits(struct cache_set *c,
struct btree *b, unsigned u64s)
{
if (b->keys.ops->is_extents) {
- /* The insert key might have to be split by cmpxchg: */
- u64s *= 2;
-
- /* And the insert key might split an existing key
+ /* The insert key might split an existing key
* (bch_insert_fixup_extent() -> BCH_EXTENT_OVERLAP_MIDDLE case:
*/
u64s += BKEY_EXTENT_U64s_MAX;
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index 1c0d019cae76..1c6b1f890680 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -1011,8 +1011,8 @@ static enum btree_insert_ret extent_insert_should_stop(struct btree_iter *iter,
*/
if (!bch_btree_node_insert_fits(c, b, insert->k.u64s))
return BTREE_INSERT_BTREE_NODE_FULL;
- else if (!journal_res_insert_fits(c, res, insert, true))
- return BTREE_INSERT_JOURNAL_RES_FULL;
+ else if (!journal_res_insert_fits(c, res, insert))
+ return BTREE_INSERT_JOURNAL_RES_FULL; /* XXX worth tracing */
else if (nr_done > 10 &&
time_after64(local_clock(), start_time +
MAX_LOCK_HOLD_TIME) &&
@@ -1095,10 +1095,25 @@ extent_insert_advance_pos(struct btree_insert_hook *hook,
: bpos_min(insert->k.p, b->key.k.p);
/* hole? */
- if (k.k && bkey_cmp(iter->pos, bkey_start_pos(k.k)) < 0)
- __extent_insert_advance_pos(hook, iter, bkey_start_pos(k.k),
- insert, bkey_s_c_null,
- res, stats);
+ if (k.k && bkey_cmp(iter->pos, bkey_start_pos(k.k)) < 0) {
+ bool might_split = bkey_cmp(iter->pos,
+ bkey_start_pos(&insert->k)) > 0;
+
+ /*
+ * If a hole causes us to split and insert a previously
+ * comitted portion, return BTREE_HOOK_NO_INSERT to recheck
+ * if we have room in journal res/btree node:
+ */
+ if (__extent_insert_advance_pos(hook, iter, bkey_start_pos(k.k),
+ insert, bkey_s_c_null, res,
+ stats) == BTREE_HOOK_NO_INSERT &&
+ might_split)
+ return BTREE_HOOK_NO_INSERT;
+ }
+
+ /* avoid redundant calls to hook fn: */
+ if (!bkey_cmp(iter->pos, next_pos))
+ return BTREE_HOOK_DO_INSERT;
return __extent_insert_advance_pos(hook, iter, next_pos,
insert, k, res, stats);
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index 368c86b8cd38..659c2d93747f 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -226,26 +226,15 @@ static inline unsigned jset_u64s(unsigned u64s)
return u64s + sizeof(struct jset_entry) / sizeof(u64);
}
-static unsigned journal_res_u64s_required(struct bkey_i *k, bool is_extents)
-{
- unsigned u64s = jset_u64s(k->k.u64s);
-
- /* For extents, cmpxchg might have to split @k in two: */
- if (is_extents)
- u64s *= 2;
- return u64s;
-}
-
static inline bool journal_res_insert_fits(struct cache_set *c,
struct journal_res *res,
- struct bkey_i *k,
- bool is_extents)
+ struct bkey_i *k)
{
/* If we're in journal replay we're not getting journal reservations: */
if (!test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags))
return true;
- return journal_res_u64s_required(k, is_extents) <= res->u64s;
+ return jset_u64s(k->k.u64s) <= res->u64s;
}
void bch_journal_start(struct cache_set *);