]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/alloc_foreground.c
Update bcachefs sources to 84505cfd37 bcachefs: Go RW before check_alloc_info()
[bcachefs-tools-debian] / libbcachefs / alloc_foreground.c
index 46f215c8bced21fec6d3614ef69a6db1c411f483..2010a9af0eb2de8a36eb74633c79dea18f17ac25 100644 (file)
@@ -312,28 +312,34 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
 
        a = bch2_alloc_to_v4(k, &a_convert);
 
-       if (genbits != (alloc_freespace_genbits(*a) >> 56)) {
-               prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
-                      "  freespace key ",
-                      genbits, alloc_freespace_genbits(*a) >> 56);
+       if (a->data_type != BCH_DATA_free) {
+               if (!test_bit(BCH_FS_CHECK_ALLOC_DONE, &c->flags)) {
+                       ob = NULL;
+                       goto err;
+               }
+
+               prt_printf(&buf, "non free bucket in freespace btree\n"
+                      "  freespace key ");
                bch2_bkey_val_to_text(&buf, c, freespace_k);
                prt_printf(&buf, "\n  ");
                bch2_bkey_val_to_text(&buf, c, k);
                bch2_trans_inconsistent(trans, "%s", buf.buf);
                ob = ERR_PTR(-EIO);
                goto err;
-
        }
 
-       if (a->data_type != BCH_DATA_free) {
-               prt_printf(&buf, "non free bucket in freespace btree\n"
-                      "  freespace key ");
+       if (genbits != (alloc_freespace_genbits(*a) >> 56) &&
+           test_bit(BCH_FS_CHECK_ALLOC_DONE, &c->flags)) {
+               prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
+                      "  freespace key ",
+                      genbits, alloc_freespace_genbits(*a) >> 56);
                bch2_bkey_val_to_text(&buf, c, freespace_k);
                prt_printf(&buf, "\n  ");
                bch2_bkey_val_to_text(&buf, c, k);
                bch2_trans_inconsistent(trans, "%s", buf.buf);
                ob = ERR_PTR(-EIO);
                goto err;
+
        }
 
        if (!test_bit(BCH_FS_CHECK_BACKPOINTERS_DONE, &c->flags)) {
@@ -506,8 +512,8 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        struct open_bucket *ob = NULL;
-       bool freespace_initialized = READ_ONCE(ca->mi.freespace_initialized);
-       u64 start = freespace_initialized ? 0 : ca->bucket_alloc_trans_early_cursor;
+       bool freespace = READ_ONCE(ca->mi.freespace_initialized);
+       u64 start = freespace ? 0 : ca->bucket_alloc_trans_early_cursor;
        u64 avail;
        struct bucket_alloc_state s = { .cur_bucket = start };
        bool waiting = false;
@@ -546,20 +552,25 @@ again:
                if (ob)
                        return ob;
        }
-
-       ob = likely(ca->mi.freespace_initialized)
+alloc:
+       ob = likely(freespace)
                ? bch2_bucket_alloc_freelist(trans, ca, reserve, &s, cl)
                : bch2_bucket_alloc_early(trans, ca, reserve, &s, cl);
 
        if (s.skipped_need_journal_commit * 2 > avail)
                bch2_journal_flush_async(&c->journal, NULL);
 
-       if (!ob && !freespace_initialized && start) {
+       if (!ob && !freespace && start) {
                start = s.cur_bucket = 0;
-               goto again;
+               goto alloc;
        }
 
-       if (!freespace_initialized)
+       if (!ob && freespace && !test_bit(BCH_FS_CHECK_ALLOC_DONE, &c->flags)) {
+               freespace = false;
+               goto alloc;
+       }
+
+       if (!freespace)
                ca->bucket_alloc_trans_early_cursor = s.cur_bucket;
 err:
        if (!ob)
@@ -1224,12 +1235,9 @@ err:
        if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty) ||
            bch2_err_matches(ret, BCH_ERR_freelist_empty))
                return cl
-                       ? -EAGAIN
+                       ? -BCH_ERR_bucket_alloc_blocked
                        : -BCH_ERR_ENOSPC_bucket_alloc;
 
-       if (bch2_err_matches(ret, BCH_ERR_insufficient_devices))
-               return -EROFS;
-
        return ret;
 }