mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 09:09:55 -04:00
bcachefs: bch2_run_explicit_recovery_pass_printbuf()
We prefer helpers that emit log messages to printbufs rather than printing them directly; that way, we can ensure that different log messages from the same event are grouped together and formatted appropriately in the dmesg log. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -400,7 +400,8 @@ static int bucket_ref_update_err(struct btree_trans *trans, struct printbuf *buf
|
||||
|
||||
__bch2_count_fsck_err(c, id, buf->buf, &repeat, &print, &suppress);
|
||||
|
||||
int ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
int ret = bch2_run_explicit_recovery_pass_printbuf(c, buf,
|
||||
BCH_RECOVERY_PASS_check_allocations);
|
||||
|
||||
if (insert) {
|
||||
print = true;
|
||||
@@ -966,14 +967,27 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
|
||||
return PTR_ERR(a);
|
||||
|
||||
if (a->v.data_type && type && a->v.data_type != type) {
|
||||
bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
log_fsck_err(trans, bucket_metadata_type_mismatch,
|
||||
"bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n"
|
||||
"while marking %s",
|
||||
iter.pos.inode, iter.pos.offset, a->v.gen,
|
||||
bch2_data_type_str(a->v.data_type),
|
||||
bch2_data_type_str(type),
|
||||
bch2_data_type_str(type));
|
||||
struct printbuf buf = PRINTBUF;
|
||||
bch2_log_msg_start(c, &buf);
|
||||
prt_printf(&buf, "bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n"
|
||||
"while marking %s\n",
|
||||
iter.pos.inode, iter.pos.offset, a->v.gen,
|
||||
bch2_data_type_str(a->v.data_type),
|
||||
bch2_data_type_str(type),
|
||||
bch2_data_type_str(type));
|
||||
|
||||
bool repeat = false, print = true, suppress = false;
|
||||
bch2_count_fsck_err(c, bucket_metadata_type_mismatch, buf.buf,
|
||||
&repeat, &print, &suppress);
|
||||
|
||||
bch2_run_explicit_recovery_pass_printbuf(c, &buf,
|
||||
BCH_RECOVERY_PASS_check_allocations);
|
||||
|
||||
if (suppress)
|
||||
prt_printf(&buf, "Ratelimiting new instances of previous error\n");
|
||||
if (print)
|
||||
bch2_print_string_as_lines(KERN_ERR, buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
ret = -BCH_ERR_metadata_bucket_inconsistency;
|
||||
goto err;
|
||||
}
|
||||
@@ -985,7 +999,6 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
|
||||
ret = bch2_trans_update(trans, &iter, &a->k_i, 0);
|
||||
}
|
||||
err:
|
||||
fsck_err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ int __bch2_topology_error(struct bch_fs *c, struct printbuf *out)
|
||||
__bch2_inconsistent_error(c, out);
|
||||
return -BCH_ERR_btree_need_topology_repair;
|
||||
} else {
|
||||
return bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology) ?:
|
||||
return bch2_run_explicit_recovery_pass_printbuf(c, out, BCH_RECOVERY_PASS_check_topology) ?:
|
||||
-BCH_ERR_btree_node_read_validate_error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ u64 bch2_recovery_passes_from_stable(u64 v)
|
||||
/*
|
||||
* For when we need to rewind recovery passes and run a pass we skipped:
|
||||
*/
|
||||
static int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
static int __bch2_run_explicit_recovery_pass(struct printbuf *out,
|
||||
struct bch_fs *c,
|
||||
enum bch_recovery_pass pass)
|
||||
{
|
||||
if (c->curr_recovery_pass == ARRAY_SIZE(recovery_pass_fns))
|
||||
@@ -115,15 +116,15 @@ static int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
if (pass < BCH_RECOVERY_PASS_set_may_go_rw &&
|
||||
c->curr_recovery_pass >= BCH_RECOVERY_PASS_set_may_go_rw) {
|
||||
if (print)
|
||||
bch_info(c, "need recovery pass %s (%u), but already rw",
|
||||
bch2_recovery_passes[pass], pass);
|
||||
prt_printf(out, "need recovery pass %s (%u), but already rw",
|
||||
bch2_recovery_passes[pass], pass);
|
||||
return -BCH_ERR_cannot_rewind_recovery;
|
||||
}
|
||||
|
||||
if (print)
|
||||
bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
|
||||
bch2_recovery_passes[pass], pass,
|
||||
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);
|
||||
prt_printf(out, "running explicit recovery pass %s (%u), currently at %s (%u)",
|
||||
bch2_recovery_passes[pass], pass,
|
||||
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);
|
||||
|
||||
c->opts.recovery_passes |= BIT_ULL(pass);
|
||||
|
||||
@@ -136,13 +137,34 @@ static int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
}
|
||||
}
|
||||
|
||||
int bch2_run_explicit_recovery_pass_printbuf(struct bch_fs *c,
|
||||
struct printbuf *out,
|
||||
enum bch_recovery_pass pass)
|
||||
{
|
||||
bch2_printbuf_make_room(out, 1024);
|
||||
out->atomic++;
|
||||
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&c->recovery_pass_lock, flags);
|
||||
int ret = __bch2_run_explicit_recovery_pass(out, c, pass);
|
||||
spin_unlock_irqrestore(&c->recovery_pass_lock, flags);
|
||||
|
||||
--out->atomic;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
enum bch_recovery_pass pass)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&c->recovery_pass_lock, flags);
|
||||
int ret = __bch2_run_explicit_recovery_pass(c, pass);
|
||||
spin_unlock_irqrestore(&c->recovery_pass_lock, flags);
|
||||
struct printbuf buf = PRINTBUF;
|
||||
bch2_log_msg_start(c, &buf);
|
||||
unsigned len = buf.pos;
|
||||
|
||||
int ret = bch2_run_explicit_recovery_pass_printbuf(c, &buf, pass);
|
||||
|
||||
if (len != buf.pos)
|
||||
bch2_print_string_as_lines(KERN_NOTICE, buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ u64 bch2_recovery_passes_from_stable(u64 v);
|
||||
|
||||
u64 bch2_fsck_recovery_passes(void);
|
||||
|
||||
int bch2_run_explicit_recovery_pass_printbuf(struct bch_fs *,
|
||||
struct printbuf *,
|
||||
enum bch_recovery_pass);
|
||||
int bch2_run_explicit_recovery_pass(struct bch_fs *, enum bch_recovery_pass);
|
||||
int bch2_run_explicit_recovery_pass_persistent_locked(struct bch_fs *, enum bch_recovery_pass);
|
||||
int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *, enum bch_recovery_pass);
|
||||
|
||||
Reference in New Issue
Block a user