Skip to content

Commit cdce109

Browse files
author
Kent Overstreet
committed
bcachefs: reconstruct_alloc cleanup
Now that we've got the errors_silent mechanism, we don't have to check if the reconstruct_alloc option is set all over the place. Also - users no longer have to explicitly select fsck and fix_errors. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 3bbed37 commit cdce109

File tree

7 files changed

+113
-95
lines changed

7 files changed

+113
-95
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,14 +1052,13 @@ int bch2_check_alloc_key(struct btree_trans *trans,
10521052
if (ret)
10531053
goto err;
10541054

1055-
if (k.k->type != discard_key_type &&
1056-
(c->opts.reconstruct_alloc ||
1057-
fsck_err(c, need_discard_key_wrong,
1058-
"incorrect key in need_discard btree (got %s should be %s)\n"
1059-
" %s",
1060-
bch2_bkey_types[k.k->type],
1061-
bch2_bkey_types[discard_key_type],
1062-
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf)))) {
1055+
if (fsck_err_on(k.k->type != discard_key_type,
1056+
c, need_discard_key_wrong,
1057+
"incorrect key in need_discard btree (got %s should be %s)\n"
1058+
" %s",
1059+
bch2_bkey_types[k.k->type],
1060+
bch2_bkey_types[discard_key_type],
1061+
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
10631062
struct bkey_i *update =
10641063
bch2_trans_kmalloc(trans, sizeof(*update));
10651064

@@ -1083,15 +1082,14 @@ int bch2_check_alloc_key(struct btree_trans *trans,
10831082
if (ret)
10841083
goto err;
10851084

1086-
if (k.k->type != freespace_key_type &&
1087-
(c->opts.reconstruct_alloc ||
1088-
fsck_err(c, freespace_key_wrong,
1089-
"incorrect key in freespace btree (got %s should be %s)\n"
1090-
" %s",
1091-
bch2_bkey_types[k.k->type],
1092-
bch2_bkey_types[freespace_key_type],
1093-
(printbuf_reset(&buf),
1094-
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf)))) {
1085+
if (fsck_err_on(k.k->type != freespace_key_type,
1086+
c, freespace_key_wrong,
1087+
"incorrect key in freespace btree (got %s should be %s)\n"
1088+
" %s",
1089+
bch2_bkey_types[k.k->type],
1090+
bch2_bkey_types[freespace_key_type],
1091+
(printbuf_reset(&buf),
1092+
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
10951093
struct bkey_i *update =
10961094
bch2_trans_kmalloc(trans, sizeof(*update));
10971095

@@ -1115,14 +1113,13 @@ int bch2_check_alloc_key(struct btree_trans *trans,
11151113
if (ret)
11161114
goto err;
11171115

1118-
if (a->gen != alloc_gen(k, gens_offset) &&
1119-
(c->opts.reconstruct_alloc ||
1120-
fsck_err(c, bucket_gens_key_wrong,
1121-
"incorrect gen in bucket_gens btree (got %u should be %u)\n"
1122-
" %s",
1123-
alloc_gen(k, gens_offset), a->gen,
1124-
(printbuf_reset(&buf),
1125-
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf)))) {
1116+
if (fsck_err_on(a->gen != alloc_gen(k, gens_offset),
1117+
c, bucket_gens_key_wrong,
1118+
"incorrect gen in bucket_gens btree (got %u should be %u)\n"
1119+
" %s",
1120+
alloc_gen(k, gens_offset), a->gen,
1121+
(printbuf_reset(&buf),
1122+
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
11261123
struct bkey_i_bucket_gens *g =
11271124
bch2_trans_kmalloc(trans, sizeof(*g));
11281125

@@ -1174,14 +1171,13 @@ int bch2_check_alloc_hole_freespace(struct btree_trans *trans,
11741171

11751172
*end = bkey_min(k.k->p, *end);
11761173

1177-
if (k.k->type != KEY_TYPE_set &&
1178-
(c->opts.reconstruct_alloc ||
1179-
fsck_err(c, freespace_hole_missing,
1180-
"hole in alloc btree missing in freespace btree\n"
1181-
" device %llu buckets %llu-%llu",
1182-
freespace_iter->pos.inode,
1183-
freespace_iter->pos.offset,
1184-
end->offset))) {
1174+
if (fsck_err_on(k.k->type != KEY_TYPE_set,
1175+
c, freespace_hole_missing,
1176+
"hole in alloc btree missing in freespace btree\n"
1177+
" device %llu buckets %llu-%llu",
1178+
freespace_iter->pos.inode,
1179+
freespace_iter->pos.offset,
1180+
end->offset)) {
11851181
struct bkey_i *update =
11861182
bch2_trans_kmalloc(trans, sizeof(*update));
11871183

fs/bcachefs/backpointers.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,7 @@ static int check_bp_exists(struct btree_trans *trans,
477477
prt_printf(&buf, "\nbp pos ");
478478
bch2_bpos_to_text(&buf, bp_iter.pos);
479479

480-
if (c->opts.reconstruct_alloc ||
481-
fsck_err(c, ptr_to_missing_backpointer, "%s", buf.buf))
480+
if (fsck_err(c, ptr_to_missing_backpointer, "%s", buf.buf))
482481
ret = bch2_bucket_backpointer_mod(trans, bucket, bp, orig_k, true);
483482

484483
goto out;

fs/bcachefs/btree_gc.c

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -593,16 +593,15 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
593593
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
594594
enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, &entry_c->ptr);
595595

596-
if (!g->gen_valid &&
597-
(c->opts.reconstruct_alloc ||
598-
fsck_err(c, ptr_to_missing_alloc_key,
599-
"bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
600-
"while marking %s",
601-
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
602-
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
603-
p.ptr.gen,
604-
(printbuf_reset(&buf),
605-
bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
596+
if (fsck_err_on(!g->gen_valid,
597+
c, ptr_to_missing_alloc_key,
598+
"bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
599+
"while marking %s",
600+
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
601+
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
602+
p.ptr.gen,
603+
(printbuf_reset(&buf),
604+
bch2_bkey_val_to_text(&buf, c, *k), buf.buf))) {
606605
if (!p.ptr.cached) {
607606
g->gen_valid = true;
608607
g->gen = p.ptr.gen;
@@ -611,16 +610,15 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
611610
}
612611
}
613612

614-
if (gen_cmp(p.ptr.gen, g->gen) > 0 &&
615-
(c->opts.reconstruct_alloc ||
616-
fsck_err(c, ptr_gen_newer_than_bucket_gen,
617-
"bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
618-
"while marking %s",
619-
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
620-
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
621-
p.ptr.gen, g->gen,
622-
(printbuf_reset(&buf),
623-
bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
613+
if (fsck_err_on(gen_cmp(p.ptr.gen, g->gen) > 0,
614+
c, ptr_gen_newer_than_bucket_gen,
615+
"bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
616+
"while marking %s",
617+
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
618+
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
619+
p.ptr.gen, g->gen,
620+
(printbuf_reset(&buf),
621+
bch2_bkey_val_to_text(&buf, c, *k), buf.buf))) {
624622
if (!p.ptr.cached) {
625623
g->gen_valid = true;
626624
g->gen = p.ptr.gen;
@@ -633,28 +631,26 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
633631
}
634632
}
635633

636-
if (gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX &&
637-
(c->opts.reconstruct_alloc ||
638-
fsck_err(c, ptr_gen_newer_than_bucket_gen,
639-
"bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
640-
"while marking %s",
641-
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
642-
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
643-
p.ptr.gen,
644-
(printbuf_reset(&buf),
645-
bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
634+
if (fsck_err_on(gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX,
635+
c, ptr_gen_newer_than_bucket_gen,
636+
"bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
637+
"while marking %s",
638+
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
639+
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
640+
p.ptr.gen,
641+
(printbuf_reset(&buf),
642+
bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))
646643
do_update = true;
647644

648-
if (!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0 &&
649-
(c->opts.reconstruct_alloc ||
650-
fsck_err(c, stale_dirty_ptr,
651-
"bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
652-
"while marking %s",
653-
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
654-
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
655-
p.ptr.gen, g->gen,
656-
(printbuf_reset(&buf),
657-
bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
645+
if (fsck_err_on(!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0,
646+
c, stale_dirty_ptr,
647+
"bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
648+
"while marking %s",
649+
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
650+
bch2_data_type_str(ptr_data_type(k->k, &p.ptr)),
651+
p.ptr.gen, g->gen,
652+
(printbuf_reset(&buf),
653+
bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))
658654
do_update = true;
659655

660656
if (data_type != BCH_DATA_btree && p.ptr.gen != g->gen)
@@ -1411,8 +1407,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
14111407
if (gen_after(old->gen, gc.gen))
14121408
return 0;
14131409

1414-
if (c->opts.reconstruct_alloc ||
1415-
fsck_err_on(new.data_type != gc.data_type, c,
1410+
if (fsck_err_on(new.data_type != gc.data_type, c,
14161411
alloc_key_data_type_wrong,
14171412
"bucket %llu:%llu gen %u has wrong data_type"
14181413
": got %s, should be %s",
@@ -1423,8 +1418,7 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
14231418
new.data_type = gc.data_type;
14241419

14251420
#define copy_bucket_field(_errtype, _f) \
1426-
if (c->opts.reconstruct_alloc || \
1427-
fsck_err_on(new._f != gc._f, c, _errtype, \
1421+
if (fsck_err_on(new._f != gc._f, c, _errtype, \
14281422
"bucket %llu:%llu gen %u data type %s has wrong " #_f \
14291423
": got %u, should be %u", \
14301424
iter->pos.inode, iter->pos.offset, \

fs/bcachefs/lru.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ static int bch2_check_lru_key(struct btree_trans *trans,
125125
goto out;
126126
}
127127

128-
if (c->opts.reconstruct_alloc ||
129-
fsck_err(c, lru_entry_bad,
128+
if (fsck_err(c, lru_entry_bad,
130129
"incorrect lru entry: lru %s time %llu\n"
131130
" %s\n"
132131
" for %s",

fs/bcachefs/recovery.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,47 @@ static bool btree_id_is_alloc(enum btree_id id)
5252
}
5353

5454
/* for -o reconstruct_alloc: */
55-
static void drop_alloc_keys(struct journal_keys *keys)
55+
static void do_reconstruct_alloc(struct bch_fs *c)
5656
{
57+
bch2_journal_log_msg(c, "dropping alloc info");
58+
bch_info(c, "dropping and reconstructing all alloc info");
59+
60+
mutex_lock(&c->sb_lock);
61+
struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
62+
63+
__set_bit_le64(BCH_RECOVERY_PASS_STABLE_check_allocations, ext->recovery_passes_required);
64+
__set_bit_le64(BCH_RECOVERY_PASS_STABLE_check_alloc_info, ext->recovery_passes_required);
65+
__set_bit_le64(BCH_RECOVERY_PASS_STABLE_check_lrus, ext->recovery_passes_required);
66+
__set_bit_le64(BCH_RECOVERY_PASS_STABLE_check_extents_to_backpointers, ext->recovery_passes_required);
67+
__set_bit_le64(BCH_RECOVERY_PASS_STABLE_check_alloc_to_lru_refs, ext->recovery_passes_required);
68+
69+
__set_bit_le64(BCH_FSCK_ERR_ptr_to_missing_alloc_key, ext->errors_silent);
70+
__set_bit_le64(BCH_FSCK_ERR_ptr_gen_newer_than_bucket_gen, ext->errors_silent);
71+
__set_bit_le64(BCH_FSCK_ERR_stale_dirty_ptr, ext->errors_silent);
72+
__set_bit_le64(BCH_FSCK_ERR_alloc_key_data_type_wrong, ext->errors_silent);
73+
__set_bit_le64(BCH_FSCK_ERR_alloc_key_gen_wrong, ext->errors_silent);
74+
__set_bit_le64(BCH_FSCK_ERR_alloc_key_dirty_sectors_wrong, ext->errors_silent);
75+
__set_bit_le64(BCH_FSCK_ERR_alloc_key_stripe_wrong, ext->errors_silent);
76+
__set_bit_le64(BCH_FSCK_ERR_alloc_key_stripe_redundancy_wrong, ext->errors_silent);
77+
__set_bit_le64(BCH_FSCK_ERR_need_discard_key_wrong, ext->errors_silent);
78+
__set_bit_le64(BCH_FSCK_ERR_freespace_key_wrong, ext->errors_silent);
79+
__set_bit_le64(BCH_FSCK_ERR_bucket_gens_key_wrong, ext->errors_silent);
80+
__set_bit_le64(BCH_FSCK_ERR_freespace_hole_missing, ext->errors_silent);
81+
__set_bit_le64(BCH_FSCK_ERR_ptr_to_missing_backpointer, ext->errors_silent);
82+
__set_bit_le64(BCH_FSCK_ERR_lru_entry_bad, ext->errors_silent);
83+
c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
84+
85+
bch2_write_super(c);
86+
mutex_unlock(&c->sb_lock);
87+
88+
c->recovery_passes_explicit |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));
89+
90+
struct journal_keys *keys = &c->journal_keys;
5791
size_t src, dst;
5892

5993
for (src = 0, dst = 0; src < keys->nr; src++)
6094
if (!btree_id_is_alloc(keys->data[src].btree_id))
6195
keys->data[dst++] = keys->data[src];
62-
6396
keys->nr = dst;
6497
}
6598

@@ -395,11 +428,8 @@ static int read_btree_roots(struct bch_fs *c)
395428
if (!r->alive)
396429
continue;
397430

398-
if (btree_id_is_alloc(i) &&
399-
c->opts.reconstruct_alloc) {
400-
c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
431+
if (btree_id_is_alloc(i) && c->opts.reconstruct_alloc)
401432
continue;
402-
}
403433

404434
if (r->error) {
405435
__fsck_err(c,
@@ -930,10 +960,8 @@ int bch2_fs_recovery(struct bch_fs *c)
930960
c->journal_replay_seq_start = last_seq;
931961
c->journal_replay_seq_end = blacklist_seq - 1;
932962

933-
if (c->opts.reconstruct_alloc) {
934-
c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
935-
drop_alloc_keys(&c->journal_keys);
936-
}
963+
if (c->opts.reconstruct_alloc)
964+
do_reconstruct_alloc(c);
937965

938966
zero_out_btree_mem_ptr(&c->journal_keys);
939967

@@ -968,9 +996,6 @@ int bch2_fs_recovery(struct bch_fs *c)
968996
if (ret)
969997
goto err;
970998

971-
if (c->opts.reconstruct_alloc)
972-
bch2_journal_log_msg(c, "dropping alloc info");
973-
974999
/*
9751000
* Skip past versions that might have possibly been used (as nonces),
9761001
* but hadn't had their pointers written:

fs/bcachefs/sb-downgrade.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ void bch2_sb_set_downgrade(struct bch_fs *c, unsigned new_minor, unsigned old_mi
259259
if (e < BCH_SB_ERR_MAX)
260260
__set_bit(e, c->sb.errors_silent);
261261
if (e < sizeof(ext->errors_silent) * 8)
262-
ext->errors_silent[e / 64] |= cpu_to_le64(BIT_ULL(e % 64));
262+
__set_bit_le64(e, ext->errors_silent);
263263
}
264264
}
265265
}

fs/bcachefs/util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,4 +864,9 @@ static inline int copy_from_user_errcode(void *to, const void __user *from, unsi
864864

865865
#endif
866866

867+
static inline void __set_bit_le64(size_t bit, __le64 *addr)
868+
{
869+
addr[bit / 64] |= cpu_to_le64(BIT_ULL(bit % 64));
870+
}
871+
867872
#endif /* _BCACHEFS_UTIL_H */

0 commit comments

Comments
 (0)