Skip to content

Commit 55936af

Browse files
author
Kent Overstreet
committed
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 <[email protected]>
1 parent 43f5ea4 commit 55936af

File tree

6 files changed

+44
-5
lines changed

6 files changed

+44
-5
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ struct bch_fs {
797797
u64 features;
798798
u64 compat;
799799
unsigned long errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)];
800+
u64 btrees_lost_data;
800801
} sb;
801802

802803

fs/bcachefs/bcachefs_format.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ struct bch_sb_field_ext {
818818
struct bch_sb_field field;
819819
__le64 recovery_passes_required[2];
820820
__le64 errors_silent[8];
821+
__le64 btrees_lost_data;
821822
};
822823

823824
struct bch_sb_field_downgrade_entry {

fs/bcachefs/btree_io.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,10 +1264,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
12641264
return retry_read;
12651265
fsck_err:
12661266
if (ret == -BCH_ERR_btree_node_read_err_want_retry ||
1267-
ret == -BCH_ERR_btree_node_read_err_must_retry)
1267+
ret == -BCH_ERR_btree_node_read_err_must_retry) {
12681268
retry_read = 1;
1269-
else
1269+
} else {
12701270
set_btree_node_read_error(b);
1271+
bch2_btree_lost_data(c, b->c.btree_id);
1272+
}
12711273
goto out;
12721274
}
12731275

@@ -1328,6 +1330,7 @@ static void btree_node_read_work(struct work_struct *work)
13281330

13291331
if (!can_retry) {
13301332
set_btree_node_read_error(b);
1333+
bch2_btree_lost_data(c, b->c.btree_id);
13311334
break;
13321335
}
13331336
}
@@ -1527,9 +1530,10 @@ static CLOSURE_CALLBACK(btree_node_read_all_replicas_done)
15271530
ret = -1;
15281531
}
15291532

1530-
if (ret)
1533+
if (ret) {
15311534
set_btree_node_read_error(b);
1532-
else if (*saw_error)
1535+
bch2_btree_lost_data(c, b->c.btree_id);
1536+
} else if (*saw_error)
15331537
bch2_btree_node_rewrite_async(c, b);
15341538

15351539
for (i = 0; i < ra->nr; i++) {
@@ -1665,6 +1669,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
16651669
bch2_fatal_error(c);
16661670

16671671
set_btree_node_read_error(b);
1672+
bch2_btree_lost_data(c, b->c.btree_id);
16681673
clear_btree_node_read_in_flight(b);
16691674
wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
16701675
printbuf_exit(&buf);

fs/bcachefs/recovery.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333

3434
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
3535

36+
void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
37+
{
38+
u64 b = BIT_ULL(btree);
39+
40+
if (!(c->sb.btrees_lost_data & b)) {
41+
bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree));
42+
43+
mutex_lock(&c->sb_lock);
44+
bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b);
45+
bch2_write_super(c);
46+
mutex_unlock(&c->sb_lock);
47+
}
48+
}
49+
3650
static bool btree_id_is_alloc(enum btree_id id)
3751
{
3852
switch (id) {
@@ -470,6 +484,7 @@ static int read_btree_roots(struct bch_fs *c)
470484
}
471485

472486
ret = 0;
487+
bch2_btree_lost_data(c, i);
473488
}
474489
}
475490

@@ -848,6 +863,14 @@ int bch2_fs_recovery(struct bch_fs *c)
848863
write_sb = true;
849864
}
850865

866+
if (c->opts.fsck &&
867+
!test_bit(BCH_FS_error, &c->flags) &&
868+
c->recovery_pass_done == BCH_RECOVERY_PASS_NR - 1 &&
869+
ext->btrees_lost_data) {
870+
ext->btrees_lost_data = 0;
871+
write_sb = true;
872+
}
873+
851874
if (c->opts.fsck &&
852875
!test_bit(BCH_FS_error, &c->flags) &&
853876
!test_bit(BCH_FS_errors_not_fixed, &c->flags)) {

fs/bcachefs/recovery.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef _BCACHEFS_RECOVERY_H
33
#define _BCACHEFS_RECOVERY_H
44

5+
void bch2_btree_lost_data(struct bch_fs *, enum btree_id);
6+
57
int bch2_journal_replay(struct bch_fs *);
68

79
int bch2_fs_recovery(struct bch_fs *);

fs/bcachefs/super-io.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,11 @@ static void bch2_sb_update(struct bch_fs *c)
527527
memset(c->sb.errors_silent, 0, sizeof(c->sb.errors_silent));
528528

529529
struct bch_sb_field_ext *ext = bch2_sb_field_get(src, ext);
530-
if (ext)
530+
if (ext) {
531531
le_bitvector_to_cpu(c->sb.errors_silent, (void *) ext->errors_silent,
532532
sizeof(c->sb.errors_silent) * 8);
533+
c->sb.btrees_lost_data = le64_to_cpu(ext->btrees_lost_data);
534+
}
533535

534536
for_each_member_device(c, ca) {
535537
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,
11621164

11631165
kfree(errors_silent);
11641166
}
1167+
1168+
prt_printf(out, "Btrees with missing data:");
1169+
prt_tab(out);
1170+
prt_bitflags(out, __bch2_btree_ids, le64_to_cpu(e->btrees_lost_data));
1171+
prt_newline(out);
11651172
}
11661173

11671174
static const struct bch_sb_field_ops bch_sb_field_ops_ext = {

0 commit comments

Comments
 (0)