When a rewrite transaction publishes via no-conflict handoff, merge_content_to
can update an already CRC-stamped initial-pending fixedkv page (copy-dest of a
concurrent split). It refreshed last_committed_crc but not the in-extent phy
checksum, so the page could be written with new content and a stale stamp.
Debug asserts only compare last_committed_crc to calc_crc32c(), so the mismatch
survived until a later cold read aborted with "fixedkv extent checksum
inconsistent".
Recalculate the CRC and call update_in_extent_chksum_field together in both
LBALeafNode and FixedKVInternalNode merge_content_to, matching
apply_delta_and_adjust_crc / update_lba_mappings.
Fixes: https://tracker.ceph.com/issues/77022
Signed-off-by: Kautilya Tripathi <kautilya.tripathi@ibm.com>
}
if (pending_version.get_last_committed_crc()) {
// if pending_version has already calculated its crc,
- // calculate it again.
- pending_version.set_last_committed_crc(pending_version.calc_crc32c());
+ // calculate it again and keep the on-page checksum in sync.
+ auto crc = pending_version.calc_crc32c();
+ pending_version.set_last_committed_crc(crc);
+ pending_version.update_in_extent_chksum_field(crc);
}
}
}
if (pending_version.is_initial_pending() &&
pending_version.get_last_committed_crc()) {
// if pending_version has already calculated its crc,
- // calculate it again.
- pending_version.set_last_committed_crc(pending_version.calc_crc32c());
+ // calculate it again and keep the on-page checksum in sync.
+ auto crc = pending_version.calc_crc32c();
+ pending_version.set_last_committed_crc(crc);
+ pending_version.update_in_extent_chksum_field(crc);
}
return modified;
}