]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
crimson/seastore: skip LBA-leaf crc check for in-place delta-overwrite extents 69053/head
authorKefu Chai <k.chai@proxmox.com>
Sat, 13 Jun 2026 04:45:03 +0000 (12:45 +0800)
committerKefu Chai <k.chai@proxmox.com>
Tue, 30 Jun 2026 07:48:14 +0000 (15:48 +0800)
commit3201a3d130e3b0d4498454db1db36c26f00d745a
treedcfdc4f100c53c379f35e7b81ba4212520949275
parentfd808e845305a5df64935e12122d4fb47b08ed0d
crimson/seastore: skip LBA-leaf crc check for in-place delta-overwrite extents

on a cold read, check_full_extent_integrity() compares the crc of the read
content against the crc stored in the LBA leaf (pin_crc). this aborts on a
RANDOM_BLOCK data extent that was overwritten via delta-based overwrite:

  abort(extent checksum inconsistent)
   4# Cache::check_full_extent_integrity()
   5# Cache::_read_extent()::{lambda}
   7# Cache::replay_delta()  (or _read_pin on the live IO path)

the leaf crc is not a valid reference for these extents. delta overwrite
mutates the extent in place to avoid touching the LBA tree, so
update_lba_mappings() skips the leaf for is_exist_mutation_pending() extents
and the pre-mutation crc stays there. the new content lands on disk later and
out-of-band, when the cleaner rewrites the modified region in place
(RandomBlockOolWriter::do_write). that write is not atomic with the leaf, so a
cold read can pick up new content against an old leaf crc.

updating the leaf crc on overwrite is not the fix. it brings back the LBA-tree
mutation (and the txn conflicts and hot-path crc) that delta overwrite exists
to avoid, and it still does not make the leaf reliable: the data write and the
leaf update happen separately, so publishing leaf=new while disk still holds
old just moves the mismatch.

so stop trusting the leaf for these extents. their content is verified at
replay, where replay_delta() applies the deltas and
CircularBoundedJournal::replay() asserts last_committed_crc == delta.final_crc.
and the content on disk is always current: modified_region accumulates every
change via union_insert and is cleared only when the in-place rewrite commits,
so do_write writes the latest content; only the leaf crc lags.

drop the leaf-crc check on read for RANDOM_BLOCK in-place-rewritable (data)
extents, but only when delta-based overwrite is enabled. with it off (the
default), overwrites go through remapping, the leaf crc stays valid, and the
check still runs for every other extent. last_committed_crc is computed
regardless, so the delta-chain check is unaffected.

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