bcachefs: Fixes for startup on very full filesystems
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 12 May 2020 00:01:07 +0000 (20:01 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:39 +0000 (17:08 -0400)
 - Always pass BTREE_INSERT_USE_RESERVE when writing alloc btree keys
 - Don't strand buckest on the copygc freelist until after recovery is
   done and we're starting copygc.

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/super.c

index 9ce53164d9acc8edbf5bc142a42266f6834f7781..559b9be50952423c4f4b4c2a6e2d0953ab400dc3 100644 (file)
@@ -315,7 +315,9 @@ retry:
        bch2_trans_update(trans, iter, &a->k_i,
                          BTREE_TRIGGER_NORUN);
        ret = bch2_trans_commit(trans, NULL, NULL,
-                               BTREE_INSERT_NOFAIL|flags);
+                               BTREE_INSERT_NOFAIL|
+                               BTREE_INSERT_USE_RESERVE|
+                               flags);
 err:
        if (ret == -EINTR)
                goto retry;
@@ -1033,7 +1035,16 @@ static int push_invalidated_bucket(struct bch_fs *c, struct bch_dev *ca, size_t
                set_current_state(TASK_INTERRUPTIBLE);
 
                spin_lock(&c->freelist_lock);
-               for (i = 0; i < RESERVE_NR; i++)
+               for (i = 0; i < RESERVE_NR; i++) {
+
+                       /*
+                        * Don't strand buckets on the copygc freelist until
+                        * after recovery is finished:
+                        */
+                       if (!test_bit(BCH_FS_STARTED, &c->flags) &&
+                           i == RESERVE_MOVINGGC)
+                               continue;
+
                        if (fifo_push(&ca->free[i], bucket)) {
                                fifo_pop(&ca->free_inc, bucket);
 
@@ -1043,6 +1054,7 @@ static int push_invalidated_bucket(struct bch_fs *c, struct bch_dev *ca, size_t
                                spin_unlock(&c->freelist_lock);
                                goto out;
                        }
+               }
 
                if (ca->allocator_state != ALLOCATOR_BLOCKED_FULL) {
                        ca->allocator_state = ALLOCATOR_BLOCKED_FULL;
index bbb0780bc4ca044554e014f21a2529af5b435445..84fb2f51e48ab0df009204785352ac66617c0303 100644 (file)
@@ -860,6 +860,8 @@ int bch2_fs_start(struct bch_fs *c)
        if (bch2_fs_init_fault("fs_start"))
                goto err;
 
+       set_bit(BCH_FS_STARTED, &c->flags);
+
        if (c->opts.read_only || c->opts.nochanges) {
                bch2_fs_read_only(c);
        } else {
@@ -871,7 +873,6 @@ int bch2_fs_start(struct bch_fs *c)
                        goto err;
        }
 
-       set_bit(BCH_FS_STARTED, &c->flags);
        print_mount_opts(c);
        ret = 0;
 out: