diff --git a/src/blockstore/blockstore_disk.cpp b/src/blockstore/blockstore_disk.cpp index 15a17f45..66683978 100644 --- a/src/blockstore/blockstore_disk.cpp +++ b/src/blockstore/blockstore_disk.cpp @@ -171,6 +171,12 @@ void blockstore_disk_t::parse_config(std::map & config { throw std::runtime_error("Data block size must be a multiple of sparse write tracking granularity"); } + if (data_block_size / bitmap_granularity < 8) + { + fprintf(stderr, "Warning: block_size (%ju) / bitmap_granularity (%ju) = %ju bits. " + "Consider using larger block_size or bitmap_granularity for better performance.\n", + data_block_size, bitmap_granularity, data_block_size / bitmap_granularity); + } if (!data_csum_type) { csum_block_size = 0; @@ -259,7 +265,7 @@ void blockstore_disk_t::calc_lengths(bool skip_meta_check) } // required metadata size block_count = data_len / data_block_size; - clean_entry_bitmap_size = data_block_size / bitmap_granularity / 8; + clean_entry_bitmap_size = (data_block_size / bitmap_granularity + 7) / 8; clean_dyn_size = clean_entry_bitmap_size*2 + (csum_block_size ? data_block_size/csum_block_size*(data_csum_type & 0xFF) : 0); recalc: diff --git a/tests/test_small_block_size.sh b/tests/test_small_block_size.sh new file mode 100755 index 00000000..bc65a0af --- /dev/null +++ b/tests/test_small_block_size.sh @@ -0,0 +1,47 @@ +#!/bin/bash -ex + +# Test for Issue #112: Integer division bug causes crash with block_size < 32KB +# This test verifies that small block sizes (4KB, 8KB, 16KB) work correctly +# with 4KB bitmap_granularity, both for aligned and unaligned I/O + +# Arrange: Set up test environment with small block sizes +export SCHEME=replicated +export OSD_COUNT=3 +export PG_COUNT=1 +export PG_SIZE=2 +export OSD_SIZE=256 + +# Test with 16KB block_size and 4KB bitmap_granularity +# This should trigger the bug: 16384 / 4096 / 8 = 4 / 8 = 0 bytes +export OFFSET_ARGS="--data_block_size 16384 --bitmap_granularity 4096" + +. `dirname $0`/run_3osds.sh + +# Act: Run I/O tests that exercise the bitmap code paths + +echo "Test 1: 128KB aligned I/O (may work even with bug)" +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so \ + -bs=128k -direct=1 -iodepth=4 -rw=randwrite \ + -etcd=$ETCD_URL -pool=1 -inode=1 -size=64M -runtime=5 + +echo "Test 2: 4KB random I/O (will crash with bug)" +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so \ + -bs=4k -direct=1 -iodepth=16 -rw=randwrite \ + -etcd=$ETCD_URL -pool=1 -inode=1 -size=64M -runtime=5 + +echo "Test 3: Mixed read/write with 4KB I/O" +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so \ + -bs=4k -direct=1 -iodepth=16 -rw=randrw -rwmixread=50 \ + -etcd=$ETCD_URL -pool=1 -inode=1 -size=64M -runtime=5 + +echo "Test 4: Sequential 4KB writes" +LD_PRELOAD="build/src/client/libfio_vitastor.so" \ + fio -thread -name=test -ioengine=build/src/client/libfio_vitastor.so \ + -bs=4k -direct=1 -iodepth=1 -rw=write \ + -etcd=$ETCD_URL -pool=1 -inode=1 -size=64M + +# Assert: If we reach here without crash, test passed +format_green "OK: 16KB block_size with 4KB bitmap_granularity works correctly"