diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-02-02 23:31:00 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:35:22 -0800 |
commit | 0b0830f979701f504e96d10f551c9ce682d18af9 (patch) | |
tree | f4009ccc5644d6e5c463218f0e94c2b21d76499e | |
parent | d1c5d6a6eae0ab473ccdd5f2a84232c1e80711e1 (diff) |
bcache: fix a bug with extent merging
-rw-r--r-- | drivers/md/bcache/bset.c | 27 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 4 |
2 files changed, 12 insertions, 19 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 016066899954..161bb5cddc68 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c @@ -856,6 +856,8 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b, * * Attempts front and back merges (if @b has a method for key merging). * + * NOTE: after calling @insert may be modified and is undefined + * * @iter is used as a hint for where to insert at, but it's not * fixed/revalidated for the insertion, that's the caller's responsibility * (because there may be other iterators to fix, it's easier to just do all of @@ -880,7 +882,6 @@ struct bkey_packed *bch_bset_insert(struct btree_keys *b, struct bkey_packed *where = bch_btree_node_iter_bset_pos(iter, b, i) ?: bset_bkey_last(i); struct bkey_packed packed, *src; - BKEY_PADDED(k) tmp; BUG_ON(bset_written(t)); BUG_ON(insert->k.u64s < BKEY_U64s); @@ -902,6 +903,10 @@ struct bkey_packed *bch_bset_insert(struct btree_keys *b, verify_insert_pos(b, prev, where, insert); + /* + * note: bch_bkey_try_merge_inline() may modify either argument + */ + /* prev is in the tree, if we merge we're done */ if (prev && bch_bkey_try_merge_inline(b, iter, prev, @@ -909,22 +914,10 @@ struct bkey_packed *bch_bset_insert(struct btree_keys *b, return NULL; if (where != bset_bkey_last(i) && - bkey_bytes(&insert->k) <= sizeof(tmp)) { - bkey_copy(&tmp.k, insert); - insert = &tmp.k; - - /* - * bch_bkey_try_merge() modifies the left argument, but we can't - * modify insert since the caller needs to be able to journal - * the key that was actually inserted (and it can't just pass us - * a copy of insert, since ->insert_fixup() might trim insert if - * this is a replace operation) - */ - if (bch_bkey_try_merge_inline(b, iter, - bkey_to_packed(insert), - where, false)) - return NULL; - } + bch_bkey_try_merge_inline(b, iter, + bkey_to_packed(insert), + where, false)) + return NULL; /* * Can we overwrite the current key, instead of doing a memmove()? diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index d49ddc24d475..0136601841e8 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -694,8 +694,6 @@ void bch_btree_insert_and_journal(struct btree_iter *iter, BUG_ON(b->level); - bch_btree_bset_insert(iter, b, node_iter, insert); - if (!btree_node_dirty(b)) { set_btree_node_dirty(b); @@ -722,6 +720,8 @@ void bch_btree_insert_and_journal(struct btree_iter *iter, insert, b->level); btree_bset_last(b)->journal_seq = cpu_to_le64(c->journal.seq); } + + bch_btree_bset_insert(iter, b, node_iter, insert); } /** |