diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-10-26 14:58:36 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:31 -0400 |
commit | ef496cd268f45351820c3d268d01bd46c8b80b04 (patch) | |
tree | c1eb51551a147dd6c205b152e82a53e7ac4176d9 /fs/bcachefs/buckets.c | |
parent | 677fc0562a237f6cfc1551e37673707096905ca7 (diff) | |
download | lwn-ef496cd268f45351820c3d268d01bd46c8b80b04.tar.gz lwn-ef496cd268f45351820c3d268d01bd46c8b80b04.zip |
bcachefs: Don't BUG_ON() sector count overflow
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>
Diffstat (limited to 'fs/bcachefs/buckets.c')
-rw-r--r-- | fs/bcachefs/buckets.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index c90c2d1b7706..f837cdda9433 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -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) |