bcachefs: bch2_alloc_write() should be writing for all devices
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 9 Jan 2021 02:20:58 +0000 (21:20 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:50 +0000 (17:08 -0400)
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: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/alloc_background.c
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_gc.c
fs/bcachefs/recovery.c

index 9920e902d383e909b0cd044ceaa195247e5af135..d93c7809d821b82d706ae14dc8b51b4a6f5446dd 100644 (file)
@@ -366,7 +366,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
        unsigned i;
        int ret = 0;
 
-       for_each_rw_member(ca, c, i) {
+       for_each_member_device(ca, c, i) {
                bch2_dev_alloc_write(c, ca, flags);
                if (ret) {
                        percpu_ref_put(&ca->io_ref);
index 9645a4edcbe82d24ceee24478b3ca1895bfed64d..799569d1778ade8db4c0e1f65c36abbb15de4736 100644 (file)
@@ -510,7 +510,7 @@ enum {
 
        /* misc: */
        BCH_FS_FIXED_GENS,
-       BCH_FS_ALLOC_WRITTEN,
+       BCH_FS_NEED_ALLOC_WRITE,
        BCH_FS_REBUILD_REPLICAS,
        BCH_FS_HOLD_BTREE_WRITES,
 };
index c390b490433aa82b32ffa6a9b8f3657ef5c2a43b..4a1d800d257e8d8f323584ffd5c3099736c6c2a1 100644 (file)
@@ -132,6 +132,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k,
                                        ptr->gen)) {
                                g2->_mark.gen   = g->_mark.gen          = ptr->gen;
                                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,
@@ -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.cached_sectors        = 0;
                                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,
                        fsck_err(c, _msg ": got %llu, should be %llu"   \
                                , ##__VA_ARGS__, 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, ...)                               \
        if (dst->_f != src->_f) {                                       \
@@ -582,7 +584,7 @@ static int bch2_gc_done(struct bch_fs *c,
                                dst->_f, src->_f);                      \
                dst->_f = src->_f;                                      \
                dst->dirty = true;                                      \
-               ret = 1;                                                \
+               set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);            \
        }
 #define copy_bucket_field(_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,
                                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;                 \
-               ret = 1;                                                \
+               set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);            \
        }
 #define copy_dev_field(_f, _msg, ...)                                  \
        copy_field(_f, "dev %u has wrong " _msg, i, ##__VA_ARGS__)
index c5da1be46444b0c71bd7f69b0d558bf06dcd5245..5a43682c26efce43ce2001d0e99fba57fb94d43d 100644 (file)
@@ -938,7 +938,7 @@ int bch2_fs_recovery(struct bch_fs *c)
        struct bch_sb_field_clean *clean = NULL;
        struct jset *last_journal_entry = NULL;
        u64 blacklist_seq, journal_seq;
-       bool write_sb = false, need_write_alloc = false;
+       bool write_sb = false;
        int ret;
 
        if (c->sb.clean)
@@ -1084,10 +1084,8 @@ use_clean:
                bch_info(c, "starting metadata mark and sweep");
                err = "error in mark and sweep";
                ret = bch2_gc(c, &c->journal_keys, true, true);
-               if (ret < 0)
-                       goto err;
                if (ret)
-                       need_write_alloc = true;
+                       goto err;
                bch_verbose(c, "mark and sweep done");
        }
 
@@ -1097,10 +1095,8 @@ use_clean:
                bch_info(c, "starting mark and sweep");
                err = "error in mark and sweep";
                ret = bch2_gc(c, &c->journal_keys, true, false);
-               if (ret < 0)
-                       goto err;
                if (ret)
-                       need_write_alloc = true;
+                       goto err;
                bch_verbose(c, "mark and sweep done");
        }
 
@@ -1124,7 +1120,8 @@ use_clean:
                goto err;
        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
                 * to do here, if we ran gc (because of fsck) which recalculated
@@ -1139,8 +1136,6 @@ use_clean:
                        goto err;
                }
                bch_verbose(c, "alloc write done");
-
-               set_bit(BCH_FS_ALLOC_WRITTEN, &c->flags);
        }
 
        if (!c->sb.clean) {