diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-12-03 20:29:09 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-18 21:14:59 -0500 |
commit | b28b848e8b8041908525b1ff837f0fc274633cb1 (patch) | |
tree | 207f118ef1a5974c15b3af02477fde5ffb16c89b | |
parent | 640c2782d855d237bfe3df5443f0e611d4ae1fee (diff) |
error handlingbcachefs_disk_groups
-rw-r--r-- | fs/bcachefs/btree_io.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/error.c | 16 | ||||
-rw-r--r-- | fs/bcachefs/error.h | 17 |
4 files changed, 35 insertions, 12 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index d805fb41886b..7ea5eeb9c746 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -1595,7 +1595,7 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b, ret = validate_bset(c, b, i, sectors, &whiteout_u64s, WRITE, false); if (ret) - bch2_inconsistent_error(c); + __bch2_fs_bug(c); return ret; } diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 007aa5ef4091..208d023e44a4 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -6,6 +6,7 @@ #include "btree_iter.h" #include "btree_locking.h" #include "debug.h" +#include "error.h" #include "extents.h" #include "journal.h" #include "keylist.h" @@ -301,11 +302,16 @@ int __bch2_btree_insert_at(struct btree_insert *trans) int ret; trans_for_each_entry(trans, i) { + const char *invalid; + BUG_ON(i->iter->level); BUG_ON(bkey_cmp(bkey_start_pos(&i->k->k), i->iter->pos)); - BUG_ON(debug_check_bkeys(c) && - bch2_bkey_invalid(c, i->iter->btree_id, - bkey_i_to_s_c(i->k))); + + invalid = bch2_bkey_invalid(c, i->iter->btree_id, + bkey_i_to_s_c(i->k)); + if (bch2_fs_bug_on(invalid, c, "updating btree with invalid key: %s", + invalid)) + return -EINVAL; } bubble_sort(trans->entries, trans->nr, btree_trans_cmp); diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index ca2a06e2e4eb..d75e1ef9a675 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -3,6 +3,22 @@ #include "io.h" #include "super.h" +void __bch2_fs_bug(struct bch_fs *c) +{ + set_bit(BCH_FS_ERROR, &c->flags); + + switch (c->opts.errors) { + case BCH_ON_ERROR_CONTINUE: + case BCH_ON_ERROR_RO: + if (bch2_fs_emergency_read_only(c)) + bch_err(c, "emergency read only"); + break; + case BCH_ON_ERROR_PANIC: + panic(bch2_fmt(c, "panic after error")); + break; + } +} + void bch2_inconsistent_error(struct bch_fs *c) { set_bit(BCH_FS_ERROR, &c->flags); diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h index ac3e96d2ae43..d59e95eb72d5 100644 --- a/fs/bcachefs/error.h +++ b/fs/bcachefs/error.h @@ -16,23 +16,24 @@ struct work_struct; /* * Very fatal logic/inconsistency errors: these indicate that we've majorly - * screwed up at runtime, i.e. it's not likely that it was just caused by the - * data on disk being inconsistent. These BUG(): - * - * XXX: audit and convert to inconsistent() checks + * screwed up at runtime, and we _must_ at least go RO */ +void __bch2_fs_bug(struct bch_fs *); #define bch2_fs_bug(c, ...) \ do { \ bch_err(c, __VA_ARGS__); \ - BUG(); \ + __bch2_fs_bug(c); \ } while (0) #define bch2_fs_bug_on(cond, c, ...) \ -do { \ - if (cond) \ +({ \ + int _ret = !!(cond); \ + \ + if (_ret) \ bch2_fs_bug(c, __VA_ARGS__); \ -} while (0) + _ret; \ +}) /* * Inconsistency errors: The on disk data is inconsistent. If these occur during |