Commit 77c320eb authored by Kent Overstreet's avatar Kent Overstreet

bcache: Add on error panic/unregister setting

Works kind of like the ext4 setting, to panic or remount read only on
errors.
Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
parent 49b1212d
...@@ -843,8 +843,14 @@ struct cache_set { ...@@ -843,8 +843,14 @@ struct cache_set {
atomic_long_t cache_read_races; atomic_long_t cache_read_races;
atomic_long_t writeback_keys_done; atomic_long_t writeback_keys_done;
atomic_long_t writeback_keys_failed; atomic_long_t writeback_keys_failed;
enum {
ON_ERROR_UNREGISTER,
ON_ERROR_PANIC,
} on_error;
unsigned error_limit; unsigned error_limit;
unsigned error_decay; unsigned error_decay;
unsigned short journal_delay_ms; unsigned short journal_delay_ms;
unsigned verify:1; unsigned verify:1;
unsigned key_merging_disabled:1; unsigned key_merging_disabled:1;
......
...@@ -305,9 +305,8 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list, ...@@ -305,9 +305,8 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list,
list_for_each_entry(i, list, list) { list_for_each_entry(i, list, list) {
BUG_ON(i->pin && atomic_read(i->pin) != 1); BUG_ON(i->pin && atomic_read(i->pin) != 1);
if (n != i->j.seq) cache_set_err_on(n != i->j.seq, s,
pr_err( "bcache: journal entries %llu-%llu missing! (replaying %llu-%llu)",
"journal entries %llu-%llu missing! (replaying %llu-%llu)\n",
n, i->j.seq - 1, start, end); n, i->j.seq - 1, start, end);
for (k = i->j.start; for (k = i->j.start;
......
...@@ -1260,7 +1260,8 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...) ...@@ -1260,7 +1260,8 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
{ {
va_list args; va_list args;
if (test_bit(CACHE_SET_STOPPING, &c->flags)) if (c->on_error != ON_ERROR_PANIC &&
test_bit(CACHE_SET_STOPPING, &c->flags))
return false; return false;
/* XXX: we can be called from atomic context /* XXX: we can be called from atomic context
...@@ -1275,6 +1276,9 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...) ...@@ -1275,6 +1276,9 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
printk(", disabling caching\n"); printk(", disabling caching\n");
if (c->on_error == ON_ERROR_PANIC)
panic("panic forced after error\n");
bch_cache_set_unregister(c); bch_cache_set_unregister(c);
return true; return true;
} }
......
...@@ -21,6 +21,12 @@ static const char * const cache_replacement_policies[] = { ...@@ -21,6 +21,12 @@ static const char * const cache_replacement_policies[] = {
NULL NULL
}; };
static const char * const error_actions[] = {
"unregister",
"panic",
NULL
};
write_attribute(attach); write_attribute(attach);
write_attribute(detach); write_attribute(detach);
write_attribute(unregister); write_attribute(unregister);
...@@ -90,6 +96,7 @@ rw_attribute(discard); ...@@ -90,6 +96,7 @@ rw_attribute(discard);
rw_attribute(running); rw_attribute(running);
rw_attribute(label); rw_attribute(label);
rw_attribute(readahead); rw_attribute(readahead);
rw_attribute(errors);
rw_attribute(io_error_limit); rw_attribute(io_error_limit);
rw_attribute(io_error_halflife); rw_attribute(io_error_halflife);
rw_attribute(verify); rw_attribute(verify);
...@@ -492,6 +499,10 @@ SHOW(__bch_cache_set) ...@@ -492,6 +499,10 @@ SHOW(__bch_cache_set)
sysfs_print(writeback_keys_failed, sysfs_print(writeback_keys_failed,
atomic_long_read(&c->writeback_keys_failed)); atomic_long_read(&c->writeback_keys_failed));
if (attr == &sysfs_errors)
return bch_snprint_string_list(buf, PAGE_SIZE, error_actions,
c->on_error);
/* See count_io_errors for why 88 */ /* See count_io_errors for why 88 */
sysfs_print(io_error_halflife, c->error_decay * 88); sysfs_print(io_error_halflife, c->error_decay * 88);
sysfs_print(io_error_limit, c->error_limit >> IO_ERROR_SHIFT); sysfs_print(io_error_limit, c->error_limit >> IO_ERROR_SHIFT);
...@@ -569,6 +580,15 @@ STORE(__bch_cache_set) ...@@ -569,6 +580,15 @@ STORE(__bch_cache_set)
sysfs_strtoul(congested_write_threshold_us, sysfs_strtoul(congested_write_threshold_us,
c->congested_write_threshold_us); c->congested_write_threshold_us);
if (attr == &sysfs_errors) {
ssize_t v = bch_read_string_list(buf, error_actions);
if (v < 0)
return v;
c->on_error = v;
}
if (attr == &sysfs_io_error_limit) if (attr == &sysfs_io_error_limit)
c->error_limit = strtoul_or_return(buf) << IO_ERROR_SHIFT; c->error_limit = strtoul_or_return(buf) << IO_ERROR_SHIFT;
...@@ -620,6 +640,7 @@ static struct attribute *bch_cache_set_files[] = { ...@@ -620,6 +640,7 @@ static struct attribute *bch_cache_set_files[] = {
&sysfs_average_key_size, &sysfs_average_key_size,
&sysfs_dirty_data, &sysfs_dirty_data,
&sysfs_errors,
&sysfs_io_error_limit, &sysfs_io_error_limit,
&sysfs_io_error_halflife, &sysfs_io_error_halflife,
&sysfs_congested, &sysfs_congested,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment