bcachefs: Fix bch2_trans_mark_dev_sb()
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 15 Apr 2021 00:25:33 +0000 (20:25 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:00 +0000 (17:09 -0400)
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/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/buckets_types.h
fs/bcachefs/journal.c
fs/bcachefs/recovery.c
fs/bcachefs/super.c

index a8a59140efbeb8e2f667afc25fc9d052548b8983..c115c76b219761c250d6cb61f2b03cdeb82220c5 100644 (file)
@@ -254,9 +254,9 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c,
 {
        struct bkey_alloc_unpacked u = bch2_alloc_unpack(k);
 
-       pr_buf(out, "gen %u oldest_gen %u data_type %u",
-              u.gen, u.oldest_gen, u.data_type);
-#define x(_name, ...)  pr_buf(out, #_name " %llu ", (u64) u._name);
+       pr_buf(out, "gen %u oldest_gen %u data_type %s",
+              u.gen, u.oldest_gen, bch2_data_types[u.data_type]);
+#define x(_name, ...)  pr_buf(out, " " #_name " %llu", (u64) u._name);
        BCH_ALLOC_FIELDS_V2()
 #undef  x
 }
index 4791f4896d6b43b1fa54260db454f02aaddfc148..297ff7d3b06e704c1edee0fd799a09a515377223 100644 (file)
@@ -2024,22 +2024,6 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
                goto out;
        }
 
-       if ((unsigned) (u.dirty_sectors + sectors) > ca->mi.bucket_size) {
-               bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
-                       "bucket %llu:%llu gen %u data type %s sector count overflow: %u + %u > %u\n"
-                       "while marking %s",
-                       iter->pos.inode, iter->pos.offset, u.gen,
-                       bch2_data_types[u.data_type ?: type],
-                       u.dirty_sectors, sectors, ca->mi.bucket_size,
-                       bch2_data_types[type]);
-               ret = -EIO;
-               goto out;
-       }
-
-       if (u.data_type         == type &&
-           u.dirty_sectors     == sectors)
-               goto out;
-
        u.data_type     = type;
        u.dirty_sectors = sectors;
 
@@ -2051,53 +2035,44 @@ out:
 }
 
 int bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
-                                   struct disk_reservation *res,
                                    struct bch_dev *ca, size_t b,
                                    enum bch_data_type type,
                                    unsigned sectors)
 {
-       return __bch2_trans_do(trans, res, NULL, 0,
-                       __bch2_trans_mark_metadata_bucket(trans, ca, b, BCH_DATA_journal,
-                                                       ca->mi.bucket_size));
-
+       return __bch2_trans_do(trans, NULL, NULL, 0,
+                       __bch2_trans_mark_metadata_bucket(trans, ca, b, type, sectors));
 }
 
 static int bch2_trans_mark_metadata_sectors(struct btree_trans *trans,
-                                           struct disk_reservation *res,
                                            struct bch_dev *ca,
                                            u64 start, u64 end,
                                            enum bch_data_type type,
                                            u64 *bucket, unsigned *bucket_sectors)
 {
-       int ret;
-
        do {
                u64 b = sector_to_bucket(ca, start);
                unsigned sectors =
                        min_t(u64, bucket_to_sector(ca, b + 1), end) - start;
 
-               if (b != *bucket) {
-                       if (*bucket_sectors) {
-                               ret = bch2_trans_mark_metadata_bucket(trans, res, ca,
-                                               *bucket, type, *bucket_sectors);
-                               if (ret)
-                                       return ret;
-                       }
+               if (b != *bucket && *bucket_sectors) {
+                       int ret = bch2_trans_mark_metadata_bucket(trans, ca, *bucket,
+                                                                 type, *bucket_sectors);
+                       if (ret)
+                               return ret;
 
-                       *bucket         = b;
-                       *bucket_sectors = 0;
+                       *bucket_sectors = 0;
                }
 
+               *bucket         = b;
                *bucket_sectors += sectors;
                start += sectors;
-       } while (!ret && start < end);
+       } while (start < end);
 
        return 0;
 }
 
 static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
-                            struct disk_reservation *res,
-                            struct bch_dev *ca)
+                                   struct bch_dev *ca)
 {
        struct bch_sb_layout *layout = &ca->disk_sb.sb->layout;
        u64 bucket = 0;
@@ -2108,14 +2083,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
                u64 offset = le64_to_cpu(layout->sb_offset[i]);
 
                if (offset == BCH_SB_SECTOR) {
-                       ret = bch2_trans_mark_metadata_sectors(trans, res, ca,
+                       ret = bch2_trans_mark_metadata_sectors(trans, ca,
                                                0, BCH_SB_SECTOR,
                                                BCH_DATA_sb, &bucket, &bucket_sectors);
                        if (ret)
                                return ret;
                }
 
-               ret = bch2_trans_mark_metadata_sectors(trans, res, ca, offset,
+               ret = bch2_trans_mark_metadata_sectors(trans, ca, offset,
                                      offset + (1 << layout->sb_max_size_bits),
                                      BCH_DATA_sb, &bucket, &bucket_sectors);
                if (ret)
@@ -2123,14 +2098,14 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
        }
 
        if (bucket_sectors) {
-               ret = bch2_trans_mark_metadata_bucket(trans, res, ca,
+               ret = bch2_trans_mark_metadata_bucket(trans, ca,
                                bucket, BCH_DATA_sb, bucket_sectors);
                if (ret)
                        return ret;
        }
 
        for (i = 0; i < ca->journal.nr; i++) {
-               ret = bch2_trans_mark_metadata_bucket(trans, res, ca,
+               ret = bch2_trans_mark_metadata_bucket(trans, ca,
                                ca->journal.buckets[i],
                                BCH_DATA_journal, ca->mi.bucket_size);
                if (ret)
@@ -2140,12 +2115,10 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
        return 0;
 }
 
-int bch2_trans_mark_dev_sb(struct bch_fs *c,
-                          struct disk_reservation *res,
-                          struct bch_dev *ca)
+int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
 {
-       return bch2_trans_do(c, res, NULL, 0,
-                       __bch2_trans_mark_dev_sb(&trans, res, ca));
+       return bch2_trans_do(c, NULL, NULL, 0,
+                       __bch2_trans_mark_dev_sb(&trans, ca));
 }
 
 /* Disk reservations: */
index cd81e6aba1b0ea132cc68b34e08976736c5cfca6..794c426e2198c95402e78a5cf40521c6f08a7895 100644 (file)
@@ -253,11 +253,9 @@ int bch2_trans_mark_update(struct btree_trans *, struct btree_iter *iter,
                           struct bkey_i *insert, unsigned);
 void bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *);
 
-int bch2_trans_mark_metadata_bucket(struct btree_trans *,
-                       struct disk_reservation *, struct bch_dev *,
-                       size_t, enum bch_data_type, unsigned);
-int bch2_trans_mark_dev_sb(struct bch_fs *, struct disk_reservation *,
-                          struct bch_dev *);
+int bch2_trans_mark_metadata_bucket(struct btree_trans *, struct bch_dev *,
+                                   size_t, enum bch_data_type, unsigned);
+int bch2_trans_mark_dev_sb(struct bch_fs *, struct bch_dev *);
 
 /* disk reservations: */
 
index 588b1a72adaec00ddc17b24df784b6540a7935b1..b2de2995c5e7f5b157a0f0359a1eac8b6bc5672d 100644 (file)
@@ -59,6 +59,11 @@ struct bch_dev_usage {
        struct {
                u64             buckets;
                u64             sectors; /* _compressed_ sectors: */
+               /*
+                * XXX
+                * Why do we have this? Isn't it just buckets * bucket_size -
+                * sectors?
+                */
                u64             fragmented;
        }                       d[BCH_DATA_NR];
 };
index af2f8528ac65ab41116705c82d14cd43e4a02c33..03d52a778074c7aec6b1f2b0ade2ce723144590d 100644 (file)
@@ -864,7 +864,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
 
                if (c && !new_fs)
                        ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
-                               bch2_trans_mark_metadata_bucket(&trans, NULL, ca,
+                               bch2_trans_mark_metadata_bucket(&trans, ca,
                                                bucket, BCH_DATA_journal,
                                                ca->mi.bucket_size));
 
index 9991a4f67163b69eba2b1174969ef172bebb8878..2dc3dee4efc8a8a38787cc06d2349473998766fe 100644 (file)
@@ -1333,10 +1333,12 @@ int bch2_fs_initialize(struct bch_fs *c)
         * Write out the superblock and journal buckets, now that we can do
         * btree updates
         */
-       err = "error writing alloc info";
-       ret = bch2_alloc_write(c, 0);
-       if (ret)
-               goto err;
+       err = "error marking superblock and journal";
+       for_each_member_device(ca, c, i) {
+               ret = bch2_trans_mark_dev_sb(c, ca);
+               if (ret)
+                       goto err;
+       }
 
        bch2_inode_init(c, &root_inode, 0, 0,
                        S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0, NULL);
index 385b41f167549e68811e3b7b943ae995ff460163..18ad2db9f4bf5483cbfab19883ecc37ce38905be 100644 (file)
@@ -1670,7 +1670,7 @@ have_slot:
        bch2_dev_usage_journal_reserve(c);
 
        err = "error marking superblock";
-       ret = bch2_trans_mark_dev_sb(c, NULL, ca);
+       ret = bch2_trans_mark_dev_sb(c, ca);
        if (ret)
                goto err_late;
 
@@ -1730,7 +1730,7 @@ int bch2_dev_online(struct bch_fs *c, const char *path)
 
        ca = bch_dev_locked(c, dev_idx);
 
-       if (bch2_trans_mark_dev_sb(c, NULL, ca)) {
+       if (bch2_trans_mark_dev_sb(c, ca)) {
                err = "bch2_trans_mark_dev_sb() error";
                goto err;
        }