mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
bcachefs: Flag btrees with missing data
We need this to know when we should attempt to reconstruct the snapshots btree Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
43f5ea4646
commit
55936afe11
|
@ -797,6 +797,7 @@ struct bch_fs {
|
||||||
u64 features;
|
u64 features;
|
||||||
u64 compat;
|
u64 compat;
|
||||||
unsigned long errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)];
|
unsigned long errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)];
|
||||||
|
u64 btrees_lost_data;
|
||||||
} sb;
|
} sb;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -818,6 +818,7 @@ struct bch_sb_field_ext {
|
||||||
struct bch_sb_field field;
|
struct bch_sb_field field;
|
||||||
__le64 recovery_passes_required[2];
|
__le64 recovery_passes_required[2];
|
||||||
__le64 errors_silent[8];
|
__le64 errors_silent[8];
|
||||||
|
__le64 btrees_lost_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bch_sb_field_downgrade_entry {
|
struct bch_sb_field_downgrade_entry {
|
||||||
|
|
|
@ -1264,10 +1264,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
|
||||||
return retry_read;
|
return retry_read;
|
||||||
fsck_err:
|
fsck_err:
|
||||||
if (ret == -BCH_ERR_btree_node_read_err_want_retry ||
|
if (ret == -BCH_ERR_btree_node_read_err_want_retry ||
|
||||||
ret == -BCH_ERR_btree_node_read_err_must_retry)
|
ret == -BCH_ERR_btree_node_read_err_must_retry) {
|
||||||
retry_read = 1;
|
retry_read = 1;
|
||||||
else
|
} else {
|
||||||
set_btree_node_read_error(b);
|
set_btree_node_read_error(b);
|
||||||
|
bch2_btree_lost_data(c, b->c.btree_id);
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1328,6 +1330,7 @@ static void btree_node_read_work(struct work_struct *work)
|
||||||
|
|
||||||
if (!can_retry) {
|
if (!can_retry) {
|
||||||
set_btree_node_read_error(b);
|
set_btree_node_read_error(b);
|
||||||
|
bch2_btree_lost_data(c, b->c.btree_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1527,9 +1530,10 @@ static CLOSURE_CALLBACK(btree_node_read_all_replicas_done)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret) {
|
||||||
set_btree_node_read_error(b);
|
set_btree_node_read_error(b);
|
||||||
else if (*saw_error)
|
bch2_btree_lost_data(c, b->c.btree_id);
|
||||||
|
} else if (*saw_error)
|
||||||
bch2_btree_node_rewrite_async(c, b);
|
bch2_btree_node_rewrite_async(c, b);
|
||||||
|
|
||||||
for (i = 0; i < ra->nr; i++) {
|
for (i = 0; i < ra->nr; i++) {
|
||||||
|
@ -1665,6 +1669,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
|
||||||
bch2_fatal_error(c);
|
bch2_fatal_error(c);
|
||||||
|
|
||||||
set_btree_node_read_error(b);
|
set_btree_node_read_error(b);
|
||||||
|
bch2_btree_lost_data(c, b->c.btree_id);
|
||||||
clear_btree_node_read_in_flight(b);
|
clear_btree_node_read_in_flight(b);
|
||||||
wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
|
wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
|
||||||
printbuf_exit(&buf);
|
printbuf_exit(&buf);
|
||||||
|
|
|
@ -33,6 +33,20 @@
|
||||||
|
|
||||||
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
|
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
|
||||||
|
|
||||||
|
void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
|
||||||
|
{
|
||||||
|
u64 b = BIT_ULL(btree);
|
||||||
|
|
||||||
|
if (!(c->sb.btrees_lost_data & b)) {
|
||||||
|
bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree));
|
||||||
|
|
||||||
|
mutex_lock(&c->sb_lock);
|
||||||
|
bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b);
|
||||||
|
bch2_write_super(c);
|
||||||
|
mutex_unlock(&c->sb_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool btree_id_is_alloc(enum btree_id id)
|
static bool btree_id_is_alloc(enum btree_id id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
@ -470,6 +484,7 @@ static int read_btree_roots(struct bch_fs *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
bch2_btree_lost_data(c, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,6 +863,14 @@ int bch2_fs_recovery(struct bch_fs *c)
|
||||||
write_sb = true;
|
write_sb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->opts.fsck &&
|
||||||
|
!test_bit(BCH_FS_error, &c->flags) &&
|
||||||
|
c->recovery_pass_done == BCH_RECOVERY_PASS_NR - 1 &&
|
||||||
|
ext->btrees_lost_data) {
|
||||||
|
ext->btrees_lost_data = 0;
|
||||||
|
write_sb = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->opts.fsck &&
|
if (c->opts.fsck &&
|
||||||
!test_bit(BCH_FS_error, &c->flags) &&
|
!test_bit(BCH_FS_error, &c->flags) &&
|
||||||
!test_bit(BCH_FS_errors_not_fixed, &c->flags)) {
|
!test_bit(BCH_FS_errors_not_fixed, &c->flags)) {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#ifndef _BCACHEFS_RECOVERY_H
|
#ifndef _BCACHEFS_RECOVERY_H
|
||||||
#define _BCACHEFS_RECOVERY_H
|
#define _BCACHEFS_RECOVERY_H
|
||||||
|
|
||||||
|
void bch2_btree_lost_data(struct bch_fs *, enum btree_id);
|
||||||
|
|
||||||
int bch2_journal_replay(struct bch_fs *);
|
int bch2_journal_replay(struct bch_fs *);
|
||||||
|
|
||||||
int bch2_fs_recovery(struct bch_fs *);
|
int bch2_fs_recovery(struct bch_fs *);
|
||||||
|
|
|
@ -527,9 +527,11 @@ static void bch2_sb_update(struct bch_fs *c)
|
||||||
memset(c->sb.errors_silent, 0, sizeof(c->sb.errors_silent));
|
memset(c->sb.errors_silent, 0, sizeof(c->sb.errors_silent));
|
||||||
|
|
||||||
struct bch_sb_field_ext *ext = bch2_sb_field_get(src, ext);
|
struct bch_sb_field_ext *ext = bch2_sb_field_get(src, ext);
|
||||||
if (ext)
|
if (ext) {
|
||||||
le_bitvector_to_cpu(c->sb.errors_silent, (void *) ext->errors_silent,
|
le_bitvector_to_cpu(c->sb.errors_silent, (void *) ext->errors_silent,
|
||||||
sizeof(c->sb.errors_silent) * 8);
|
sizeof(c->sb.errors_silent) * 8);
|
||||||
|
c->sb.btrees_lost_data = le64_to_cpu(ext->btrees_lost_data);
|
||||||
|
}
|
||||||
|
|
||||||
for_each_member_device(c, ca) {
|
for_each_member_device(c, ca) {
|
||||||
struct bch_member m = bch2_sb_member_get(src, ca->dev_idx);
|
struct bch_member m = bch2_sb_member_get(src, ca->dev_idx);
|
||||||
|
@ -1162,6 +1164,11 @@ static void bch2_sb_ext_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||||
|
|
||||||
kfree(errors_silent);
|
kfree(errors_silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prt_printf(out, "Btrees with missing data:");
|
||||||
|
prt_tab(out);
|
||||||
|
prt_bitflags(out, __bch2_btree_ids, le64_to_cpu(e->btrees_lost_data));
|
||||||
|
prt_newline(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bch_sb_field_ops bch_sb_field_ops_ext = {
|
static const struct bch_sb_field_ops bch_sb_field_ops_ext = {
|
||||||
|
|
Loading…
Reference in a new issue