From 893aa36e0111c1418f260bd8d1092b7f22ea010e Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Tue, 20 Oct 2020 01:04:07 +0900 Subject: [PATCH] sys/vfs/hammer2: Don't use 1 byte size for 0 radix bits Not using 1 byte size for 0 radix bits is part of ondisk spec. This may not be expected to happen in these cases, but other ones always consider 0 radix or assert radix != 0. -- * WARNING! A radix of 0 (such as when data_off is all 0's) is a special * case which means no data associated with the blockref, and * not the '1 byte' it would otherwise calculate to. --- sys/vfs/hammer2/hammer2_chain.c | 8 ++++++-- sys/vfs/hammer2/hammer2_io.c | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sys/vfs/hammer2/hammer2_chain.c b/sys/vfs/hammer2/hammer2_chain.c index f5e6d9ee33..b51ab32e43 100644 --- a/sys/vfs/hammer2/hammer2_chain.c +++ b/sys/vfs/hammer2/hammer2_chain.c @@ -1833,8 +1833,12 @@ hammer2_chain_modify(hammer2_chain_t *chain, hammer2_tid_t mtid, */ if (dedup_off) { chain->bref.data_off = dedup_off; - chain->bytes = 1 << (dedup_off & - HAMMER2_OFF_MASK_RADIX); + if ((int)(dedup_off & HAMMER2_OFF_MASK_RADIX)) + chain->bytes = 1 << + (int)(dedup_off & + HAMMER2_OFF_MASK_RADIX); + else + chain->bytes = 0; chain->error = 0; atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED); diff --git a/sys/vfs/hammer2/hammer2_io.c b/sys/vfs/hammer2/hammer2_io.c index 2b69035b98..b419f7ddae 100644 --- a/sys/vfs/hammer2/hammer2_io.c +++ b/sys/vfs/hammer2/hammer2_io.c @@ -138,7 +138,10 @@ hammer2_io_alloc(hammer2_dev_t *hmp, hammer2_key_t data_off, uint8_t btype, psize = HAMMER2_PBUFSIZE; pmask = ~(hammer2_off_t)(psize - 1); - lsize = 1 << (int)(data_off & HAMMER2_OFF_MASK_RADIX); + if ((int)(data_off & HAMMER2_OFF_MASK_RADIX)) + lsize = 1 << (int)(data_off & HAMMER2_OFF_MASK_RADIX); + else + lsize = 0; lbase = data_off & ~HAMMER2_OFF_MASK_RADIX; pbase = lbase & pmask; @@ -785,7 +788,10 @@ hammer2_io_dedup_set(hammer2_dev_t *hmp, hammer2_blockref_t *bref) int isgood; dio = hammer2_io_alloc(hmp, bref->data_off, bref->type, 1, &isgood); - lsize = 1 << (int)(bref->data_off & HAMMER2_OFF_MASK_RADIX); + if ((int)(bref->data_off & HAMMER2_OFF_MASK_RADIX)) + lsize = 1 << (int)(bref->data_off & HAMMER2_OFF_MASK_RADIX); + else + lsize = 0; mask = hammer2_dedup_mask(dio, bref->data_off, lsize); atomic_clear_64(&dio->dedup_valid, mask); atomic_set_64(&dio->dedup_alloc, mask); -- 2.41.0