DF-2652 / fix.diff
--- a/sys/vfs/hammer2/hammer2_freemap.c +++ b/sys/vfs/hammer2/hammer2_freemap.c @@ -1070,7 +1070,15 @@ /* * Calculate the bitmask (runs in 2-bit pairs). */ - start = ((int)(data_off >> HAMMER2_FREEMAP_BLOCK_RADIX) & 15) * 2; + /* + * DF-2652: each bitmapq[] element covers 32 x 16KB blocks + * (HAMMER2_BMAP_BLOCKS_PER_ELEMENT), so the block number within + * the element is 5 bits, not 4. The old '& 15' made every + * recovery/dedup fixup for blocks 16..31 of a 512KB element mark + * the wrong 16KB chunk, leaving live blocks marked free. + */ + start = ((int)(data_off >> HAMMER2_FREEMAP_BLOCK_RADIX) & + (HAMMER2_BMAP_BLOCKS_PER_ELEMENT - 1)) * 2; //bmmask01 = (hammer2_bitmap_t)1 << start; //bmmask10 = (hammer2_bitmap_t)2 << start; bmmask11 = (hammer2_bitmap_t)3 << start; |