bcachefs: Don't BUG_ON() sector count overflow
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 26 Oct 2019 18:58:36 +0000 (14:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:31 +0000 (17:08 -0400)
Return an error instead (still work in progress...)

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/buckets.c

index c90c2d1b77063490f9f0ca401f58637035050c30..f837cdda94338c3bece0e5cfc7c3c9def28440ea 100644 (file)
@@ -1464,7 +1464,7 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
        struct bkey_s_c k;
        struct bkey_alloc_unpacked u;
        struct bkey_i_alloc *a;
-       unsigned old;
+       u16 *dst_sectors;
        bool overflow;
        int ret;
 
@@ -1519,22 +1519,24 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
                goto out;
        }
 
-       if (!p.ptr.cached) {
-               old = u.dirty_sectors;
-               overflow = checked_add(u.dirty_sectors, sectors);
-       } else {
-               old = u.cached_sectors;
-               overflow = checked_add(u.cached_sectors, sectors);
+       dst_sectors = !p.ptr.cached
+               ? &u.dirty_sectors
+               : &u.cached_sectors;
+
+       overflow = checked_add(*dst_sectors, sectors);
+
+       if (overflow) {
+               bch2_fs_inconsistent(c,
+                       "bucket sector count overflow: %u + %lli > U16_MAX",
+                       *dst_sectors, sectors);
+               /* return an error indicating that we need full fsck */
+               ret = -EIO;
+               goto out;
        }
 
        u.data_type = u.dirty_sectors || u.cached_sectors
                ? data_type : 0;
 
-       bch2_fs_inconsistent_on(overflow, c,
-               "bucket sector count overflow: %u + %lli > U16_MAX",
-               old, sectors);
-       BUG_ON(overflow);
-
        a = trans_update_key(trans, iter, BKEY_ALLOC_U64s_MAX);
        ret = PTR_ERR_OR_ZERO(a);
        if (ret)