summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/bkey.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-03-21 04:55:36 +0100
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 23:08:54 +0200
commite01dacf76c0c6a5fc6963b7857773b3d58740acb (patch)
tree6fd41c33ecef8708c2d1732cc68ad835475cfc2a /fs/bcachefs/bkey.c
parentbcachefs: Scan for old btree nodes if necessary on mount (diff)
downloadlinux-e01dacf76c0c6a5fc6963b7857773b3d58740acb.tar.xz
linux-e01dacf76c0c6a5fc6963b7857773b3d58740acb.zip
bcachefs: Fix bkey format generation for 32 bit fields
Having a packed format that can represent a field larger than the unpacked type breaks bkey_packed_successor() assertions - we need to fix this to start using the snapshot filed. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/bkey.c')
-rw-r--r--fs/bcachefs/bkey.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/bcachefs/bkey.c b/fs/bcachefs/bkey.c
index 6417307f42b9..aeac07e2cb32 100644
--- a/fs/bcachefs/bkey.c
+++ b/fs/bcachefs/bkey.c
@@ -554,7 +554,12 @@ void bch2_bkey_format_add_pos(struct bkey_format_state *s, struct bpos p)
static void set_format_field(struct bkey_format *f, enum bch_bkey_fields i,
unsigned bits, u64 offset)
{
- offset = bits == 64 ? 0 : min(offset, U64_MAX - ((1ULL << bits) - 1));
+ unsigned unpacked_bits = bch2_bkey_format_current.bits_per_field[i];
+ u64 unpacked_max = ~((~0ULL << 1) << (unpacked_bits - 1));
+
+ bits = min(bits, unpacked_bits);
+
+ offset = bits == unpacked_bits ? 0 : min(offset, unpacked_max - ((1ULL << bits) - 1));
f->bits_per_field[i] = bits;
f->field_offset[i] = cpu_to_le64(offset);