Commit 4291a331 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: bch2_alloc_write() should be writing for all devices

Alloc info isn't stored on a particular device, it makes no sense to
only be writing it out for rw members - this was causing fsck to not fix
alloc info errors, oops.

Also, make sure we write out alloc info in other repair paths.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent dcf64dfb
...@@ -366,7 +366,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags) ...@@ -366,7 +366,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
unsigned i; unsigned i;
int ret = 0; int ret = 0;
for_each_rw_member(ca, c, i) { for_each_member_device(ca, c, i) {
bch2_dev_alloc_write(c, ca, flags); bch2_dev_alloc_write(c, ca, flags);
if (ret) { if (ret) {
percpu_ref_put(&ca->io_ref); percpu_ref_put(&ca->io_ref);
......
...@@ -510,7 +510,7 @@ enum { ...@@ -510,7 +510,7 @@ enum {
/* misc: */ /* misc: */
BCH_FS_FIXED_GENS, BCH_FS_FIXED_GENS,
BCH_FS_ALLOC_WRITTEN, BCH_FS_NEED_ALLOC_WRITE,
BCH_FS_REBUILD_REPLICAS, BCH_FS_REBUILD_REPLICAS,
BCH_FS_HOLD_BTREE_WRITES, BCH_FS_HOLD_BTREE_WRITES,
}; };
......
...@@ -132,6 +132,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k, ...@@ -132,6 +132,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k,
ptr->gen)) { ptr->gen)) {
g2->_mark.gen = g->_mark.gen = ptr->gen; g2->_mark.gen = g->_mark.gen = ptr->gen;
g2->gen_valid = g->gen_valid = true; g2->gen_valid = g->gen_valid = true;
set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);
} }
if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c, if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c,
...@@ -145,6 +146,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k, ...@@ -145,6 +146,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k,
g2->_mark.dirty_sectors = 0; g2->_mark.dirty_sectors = 0;
g2->_mark.cached_sectors = 0; g2->_mark.cached_sectors = 0;
set_bit(BCH_FS_FIXED_GENS, &c->flags); set_bit(BCH_FS_FIXED_GENS, &c->flags);
set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);
} }
} }
} }
...@@ -571,7 +573,7 @@ static int bch2_gc_done(struct bch_fs *c, ...@@ -571,7 +573,7 @@ static int bch2_gc_done(struct bch_fs *c,
fsck_err(c, _msg ": got %llu, should be %llu" \ fsck_err(c, _msg ": got %llu, should be %llu" \
, ##__VA_ARGS__, dst->_f, src->_f); \ , ##__VA_ARGS__, dst->_f, src->_f); \
dst->_f = src->_f; \ dst->_f = src->_f; \
ret = 1; \ set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags); \
} }
#define copy_stripe_field(_f, _msg, ...) \ #define copy_stripe_field(_f, _msg, ...) \
if (dst->_f != src->_f) { \ if (dst->_f != src->_f) { \
...@@ -582,7 +584,7 @@ static int bch2_gc_done(struct bch_fs *c, ...@@ -582,7 +584,7 @@ static int bch2_gc_done(struct bch_fs *c,
dst->_f, src->_f); \ dst->_f, src->_f); \
dst->_f = src->_f; \ dst->_f = src->_f; \
dst->dirty = true; \ dst->dirty = true; \
ret = 1; \ set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags); \
} }
#define copy_bucket_field(_f) \ #define copy_bucket_field(_f) \
if (dst->b[b].mark._f != src->b[b].mark._f) { \ if (dst->b[b].mark._f != src->b[b].mark._f) { \
...@@ -593,7 +595,7 @@ static int bch2_gc_done(struct bch_fs *c, ...@@ -593,7 +595,7 @@ static int bch2_gc_done(struct bch_fs *c,
bch2_data_types[dst->b[b].mark.data_type],\ bch2_data_types[dst->b[b].mark.data_type],\
dst->b[b].mark._f, src->b[b].mark._f); \ dst->b[b].mark._f, src->b[b].mark._f); \
dst->b[b]._mark._f = src->b[b].mark._f; \ dst->b[b]._mark._f = src->b[b].mark._f; \
ret = 1; \ set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags); \
} }
#define copy_dev_field(_f, _msg, ...) \ #define copy_dev_field(_f, _msg, ...) \
copy_field(_f, "dev %u has wrong " _msg, i, ##__VA_ARGS__) copy_field(_f, "dev %u has wrong " _msg, i, ##__VA_ARGS__)
......
...@@ -938,7 +938,7 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -938,7 +938,7 @@ int bch2_fs_recovery(struct bch_fs *c)
struct bch_sb_field_clean *clean = NULL; struct bch_sb_field_clean *clean = NULL;
struct jset *last_journal_entry = NULL; struct jset *last_journal_entry = NULL;
u64 blacklist_seq, journal_seq; u64 blacklist_seq, journal_seq;
bool write_sb = false, need_write_alloc = false; bool write_sb = false;
int ret; int ret;
if (c->sb.clean) if (c->sb.clean)
...@@ -1084,10 +1084,8 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -1084,10 +1084,8 @@ int bch2_fs_recovery(struct bch_fs *c)
bch_info(c, "starting metadata mark and sweep"); bch_info(c, "starting metadata mark and sweep");
err = "error in mark and sweep"; err = "error in mark and sweep";
ret = bch2_gc(c, &c->journal_keys, true, true); ret = bch2_gc(c, &c->journal_keys, true, true);
if (ret < 0)
goto err;
if (ret) if (ret)
need_write_alloc = true; goto err;
bch_verbose(c, "mark and sweep done"); bch_verbose(c, "mark and sweep done");
} }
...@@ -1097,10 +1095,8 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -1097,10 +1095,8 @@ int bch2_fs_recovery(struct bch_fs *c)
bch_info(c, "starting mark and sweep"); bch_info(c, "starting mark and sweep");
err = "error in mark and sweep"; err = "error in mark and sweep";
ret = bch2_gc(c, &c->journal_keys, true, false); ret = bch2_gc(c, &c->journal_keys, true, false);
if (ret < 0)
goto err;
if (ret) if (ret)
need_write_alloc = true; goto err;
bch_verbose(c, "mark and sweep done"); bch_verbose(c, "mark and sweep done");
} }
...@@ -1124,7 +1120,8 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -1124,7 +1120,8 @@ int bch2_fs_recovery(struct bch_fs *c)
goto err; goto err;
bch_verbose(c, "journal replay done"); bch_verbose(c, "journal replay done");
if (need_write_alloc && !c->opts.nochanges) { if (test_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags) &&
!c->opts.nochanges) {
/* /*
* note that even when filesystem was clean there might be work * note that even when filesystem was clean there might be work
* to do here, if we ran gc (because of fsck) which recalculated * to do here, if we ran gc (because of fsck) which recalculated
...@@ -1139,8 +1136,6 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -1139,8 +1136,6 @@ int bch2_fs_recovery(struct bch_fs *c)
goto err; goto err;
} }
bch_verbose(c, "alloc write done"); bch_verbose(c, "alloc write done");
set_bit(BCH_FS_ALLOC_WRITTEN, &c->flags);
} }
if (!c->sb.clean) { if (!c->sb.clean) {
......
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