summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-07-16 03:44:31 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-07-16 03:45:21 -0400
commit821d66df4406ab1be7de8cc79e5ae0ffae265ff0 (patch)
treece640155d073ab74e5c44983ca0ffd3dfc87ddc0
parent20ae9b49848ceb416966fbfddbab9bb403cf2678 (diff)
bcachefs: Fix a bug when dropping invalid btree keys
There was a missing set_btree_bset_end() call, leading to popped assertions later. Also add a quick and dirty debug option for injecting invalid keys. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/bcachefs.h6
-rw-r--r--fs/bcachefs/bkey.h8
-rw-r--r--fs/bcachefs/btree_io.c5
-rw-r--r--fs/bcachefs/btree_update_leaf.c12
4 files changed, 20 insertions, 11 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 1482b80a8672..41ec25b6d42b 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -262,7 +262,11 @@ do { \
BCH_DEBUG_PARAM(journal_seq_verify, \
"Store the journal sequence number in the version " \
"number of every btree key, and verify that btree " \
- "update ordering is preserved during recovery")
+ "update ordering is preserved during recovery") \
+ BCH_DEBUG_PARAM(inject_invalid_keys, \
+ "Store the journal sequence number in the version " \
+ "number of every btree key, and verify that btree " \
+ "update ordering is preserved during recovery") \
#define BCH_DEBUG_PARAMS_ALL() BCH_DEBUG_PARAMS_ALWAYS() BCH_DEBUG_PARAMS_DEBUG()
diff --git a/fs/bcachefs/bkey.h b/fs/bcachefs/bkey.h
index 2f62bd8e3258..bd1d21b0e49b 100644
--- a/fs/bcachefs/bkey.h
+++ b/fs/bcachefs/bkey.h
@@ -206,14 +206,12 @@ void bch2_bkey_swab_key(const struct bkey_format *, struct bkey_packed *);
static __always_inline int bversion_cmp(struct bversion l, struct bversion r)
{
- if (l.hi != r.hi)
- return l.hi < r.hi ? -1 : 1;
- if (l.lo != r.lo)
- return l.lo < r.lo ? -1 : 1;
- return 0;
+ return (l.hi > r.hi) - (l.hi < r.hi) ?:
+ (l.lo > r.lo) - (l.lo < r.lo);
}
#define ZERO_VERSION ((struct bversion) { .hi = 0, .lo = 0 })
+#define MAX_VERSION ((struct bversion) { .hi = ~0, .lo = ~0ULL })
static __always_inline int bversion_zero(struct bversion v)
{
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
index 847dfd685eac..94f56dbbeac3 100644
--- a/fs/bcachefs/btree_io.c
+++ b/fs/bcachefs/btree_io.c
@@ -1298,7 +1298,9 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
struct bkey_s_c u = bkey_disassemble(b, k, &tmp);
const char *invalid = bch2_bkey_val_invalid(c, type, u);
- if (invalid) {
+ if (invalid ||
+ (inject_invalid_keys(c) &&
+ !bversion_cmp(u.k->version, MAX_VERSION))) {
char buf[160];
bch2_bkey_val_to_text(c, type, buf, sizeof(buf), u);
@@ -1310,6 +1312,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
i->u64s = cpu_to_le16(le16_to_cpu(i->u64s) - k->u64s);
memmove_u64s_down(k, bkey_next(k),
(u64 *) vstruct_end(i) - (u64 *) k);
+ set_btree_bset_end(b, b->set);
continue;
}
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 588a1997e5ee..00e711116769 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -354,10 +354,14 @@ static inline int do_btree_insert_at(struct btree_insert *trans,
}
}
- if (journal_seq_verify(c) &&
- !(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))
- trans_for_each_entry(trans, i)
- i->k->k.version.lo = trans->journal_res.seq;
+ if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) {
+ if (journal_seq_verify(c))
+ trans_for_each_entry(trans, i)
+ i->k->k.version.lo = trans->journal_res.seq;
+ else if (inject_invalid_keys(c))
+ trans_for_each_entry(trans, i)
+ i->k->k.version = MAX_VERSION;
+ }
trans_for_each_entry(trans, i) {
switch (btree_insert_key_leaf(trans, i)) {