fix: logic error in boundary check for "exactly two partial blocks" during read request merging #80

Merged
vitalif merged 1 commits from changwei.ye/vitastor:fix-blockstore-read-merge-boundary into master 2026-09-05 00:17:40 +03:00

1 Commits

Author SHA1 Message Date
ye.changwei
ed1d3a9a3f fix: logic error in boundary check for "exactly two partial blocks" during read request merging
When a read request is expanded outwards to align with checksum boundaries, `blk_end` becomes a
multiple of `csum_block_size`. The original code used `blk_end/dsk.csum_block_size ==
blk_start/dsk.csum_block_size+1` to determine whether this request with padding crosses exactly two
checksum blocks. However, since `blk_end` perfectly aligns with the physical boundary, the division
here will inevitably cause a carry, rendering the condition invalid. This incorrectly caused the
engine to split an I/O that should have been issued at once into multiple separate I/O requests,
increasing unnecessary memcpy overhead.

For example, in a real scenario (32KB csum_block_size):
- User reads logical range 28KB ~ 36KB (start=28672, end=36864). The write record (wr) spans 16KB ~
  64KB, so the initial logical clipping leaves start and end unchanged.
- To verify checksum, the engine expands the physical boundary: blk_start=0, blk_end=65536.
- After the second MVCC record clipping on physical boundaries, the effective read boundary of the
  physical data is 16KB ~ 64KB (blk_start=16384, blk_end=65536).
- Physically, these are exactly two adjacent partial blocks (16K~32K and 32K~64K, with padding waste
  at both ends). For performance, they should be read in a single I/O.
- But the original code executed: `65536/32768 (i.e., 2) == 16384/32768 (i.e., 0) + 1`, evaluating
  to `2 == 1` (False).
- As a result, this read was sub-optimally split into two independent I/Os (16K~32K and 32K~64K).

Fixing the condition to `(blk_end-1)/dsk.csum_block_size` accurately finds the block that actually
contains the last valid byte, restoring the expected read merging behavior of this branch and
avoiding breaking the zero-copy fallback optimization.
2026-09-01 09:36:35 +08:00