]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/seastore: use DMA alignment for block size instead of stat
authorKefu Chai <tchaikov@gmail.com>
Fri, 10 Oct 2025 03:04:50 +0000 (11:04 +0800)
committerKefu Chai <tchaikov@gmail.com>
Fri, 10 Oct 2025 03:18:18 +0000 (11:18 +0800)
Before this fix, BlockSegmentManager used stat.block_size (typically 512
bytes from file_stat()) as the alignment requirement for writes. However,
Seastar's DMA engine requires alignment to disk_write_dma_alignment()
(typically 4096 bytes, the logical block size) for performant writes.

This mismatch caused failures in BlockSegmentManager::segment_write():

1. Crimson believed block_size was 512 bytes (from file_stat())
2. Crimson prepared 512-byte aligned buffers for writing
3. Seastar's internal::sanitize_iovecs() trimmed the unaligned portions
   based on the actual 4096-byte DMA alignment requirement
4. This left an empty buffer (512 bytes trimmed from 512-byte buffer)
5. The write operation returned 0 bytes written
6. The assertion 'written != len' failed in do_writev()

The fix queries the actual DMA alignment requirement from Seastar via
file.disk_write_dma_alignment() and uses that as block_size throughout
the segment manager. This ensures all writes are properly aligned for
Seastar's DMA engine.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
src/crimson/os/seastore/segment_manager/block.cc

index 36b7d0ed53cede7d0ddd68f64c0d41717e26e139..4bda6cfbeaa589f73bb212fc23a97b40058480ca 100644 (file)
@@ -267,6 +267,9 @@ open_device_ret open_device(
     ).then([stat, &path, FNAME](auto file) mutable {
       return file.size().then([stat, file, &path, FNAME](auto size) mutable {
         stat.size = size;
+        // Use Seastar's DMA alignment requirement instead of stat's block_size
+        // to ensure writes are properly aligned for optimal performance
+        stat.block_size = file.disk_write_dma_alignment();
         INFO("path={} successful, size=0x{:x}, block_size=0x{:x}",
              path, stat.size, stat.block_size);
         return std::make_pair(file, stat);