summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-12-03 20:29:09 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-02-18 21:14:59 -0500
commitb28b848e8b8041908525b1ff837f0fc274633cb1 (patch)
tree207f118ef1a5974c15b3af02477fde5ffb16c89b
parent640c2782d855d237bfe3df5443f0e611d4ae1fee (diff)
error handlingbcachefs_disk_groups
-rw-r--r--fs/bcachefs/btree_io.c2
-rw-r--r--fs/bcachefs/btree_update_leaf.c12
-rw-r--r--fs/bcachefs/error.c16
-rw-r--r--fs/bcachefs/error.h17
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