summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-05-14 01:41:57 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-05-14 23:02:24 -0400
commit6afd007c0b357ee48c2c2807fc92e51b7beb522b (patch)
treee87e1b1606d49c5e951276456d22eb86cb2e9812
parentc3d801598235f9c0f43a93f38dca55a997352c08 (diff)
__bch2_bkey_unpack_key(): avoid unaligned access
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/bkey.c16
-rw-r--r--fs/bcachefs/btree_types.h1
2 files changed, 11 insertions, 6 deletions
diff --git a/fs/bcachefs/bkey.c b/fs/bcachefs/bkey.c
index e16f8541d863..128d96766c0d 100644
--- a/fs/bcachefs/bkey.c
+++ b/fs/bcachefs/bkey.c
@@ -23,9 +23,9 @@ struct bkey_format_processed bch2_bkey_format_postprocess(const struct bkey_form
{
struct bkey_format_processed ret = { .f = f, .aligned = true };
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- unsigned bit_offset = f.key_u64s * 64;
+ unsigned offset = f.key_u64s * 64;
#else
- unsigned bit_offset = KEY_PACKED_BITS_START;
+ unsigned offset = KEY_PACKED_BITS_START;
#endif
for (unsigned i = 0; i < BKEY_NR_FIELDS; i++) {
@@ -37,13 +37,16 @@ struct bkey_format_processed bch2_bkey_format_postprocess(const struct bkey_form
}
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- bit_offset -= bits;
+ offset -= bits;
#endif
- ret.offset[i] = bit_offset / 8;
+
+ ret.shift[i] = min(offset & 63, 64 - bits);
+ ret.offset[i] = (offset - ret.shift[i]) / 8;
+ ret.mask[i] = bits ? ~0ULL >> (64 - bits) : 0;
+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- bit_offset += bits;
+ offset += bits;
#endif
- ret.mask[i] = bits ? ~0ULL >> (64 - bits) : 0;
}
return ret;
@@ -223,6 +226,7 @@ static u64 get_aligned_field(const struct bkey_format_processed *f,
{
u64 v = get_unaligned((u64 *) (((u8 *) in->_data) + f->offset[field_idx]));
+ v >>= f->shift[field_idx];
v &= f->mask[field_idx];
return v + le64_to_cpu(f->f.field_offset[field_idx]);
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h
index b76486ffbba1..38c3ec685240 100644
--- a/fs/bcachefs/btree_types.h
+++ b/fs/bcachefs/btree_types.h
@@ -72,6 +72,7 @@ struct bkey_format_processed {
struct bkey_format f;
bool aligned;
u8 offset[6];
+ u8 shift[6];
u64 mask[6];
};