Skip to content

Commit eec4d34

Browse files
copilot nits
1 parent 8768b5d commit eec4d34

1 file changed

Lines changed: 20 additions & 15 deletions

File tree

runtime/src/utils/buffer/paged/append.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,9 @@ impl<B: Blob> Append<B> {
798798
///
799799
/// Since larger valid lengths are authoritative, a shorter CRC cannot simply be written next to
800800
/// the old CRC. We first stage the shorter slot with length 0, then make its length durable,
801-
/// then invalidate the old longer slot. A crash during any phase recovers either the old longer
802-
/// page or the new shorter page, but never loses the whole page or fabricates a larger length.
801+
/// then clear the old slot's CRC bytes before clearing its length bytes. A crash during any
802+
/// phase recovers either the old longer page or the new shorter page, but never loses the whole
803+
/// page or fabricates a larger length.
803804
async fn sync_partial_page_shrink(
804805
blob: &B,
805806
page: u64,
@@ -821,36 +822,40 @@ impl<B: Blob> Append<B> {
821822
} else {
822823
0
823824
};
825+
let new_slot_offset = crc_start
826+
.checked_add(new_slot_start as u64)
827+
.ok_or(Error::OffsetOverflow)?;
824828
let staged_slot = Self::checksum_slot_bytes(0, new_crc);
825-
blob.write_at(crc_start + new_slot_start as u64, staged_slot.to_vec())
829+
blob.write_at(new_slot_offset, staged_slot.to_vec())
826830
.await?;
827831
blob.sync().await?;
828832

829-
blob.write_at(
830-
crc_start + new_slot_start as u64,
831-
new_len.to_be_bytes().to_vec(),
832-
)
833-
.await?;
833+
blob.write_at(new_slot_offset, new_len.to_be_bytes().to_vec())
834+
.await?;
834835
blob.sync().await?;
835836

836837
let old_slot_start = if new_slot_start == 0 {
837838
CHECKSUM_SLOT_SIZE
838839
} else {
839840
0
840841
};
842+
let old_slot_offset = crc_start
843+
.checked_add(old_slot_start as u64)
844+
.ok_or(Error::OffsetOverflow)?;
841845
let len_size = std::mem::size_of::<u16>();
842846
let crc_size = CHECKSUM_SLOT_SIZE - len_size;
843-
blob.write_at(
844-
crc_start + old_slot_start as u64 + len_size as u64,
845-
vec![0u8; crc_size],
846-
)
847-
.await?;
848-
blob.sync().await?;
847+
let old_crc_offset = old_slot_offset
848+
.checked_add(len_size as u64)
849+
.ok_or(Error::OffsetOverflow)?;
849850

850-
blob.write_at(crc_start + old_slot_start as u64, vec![0u8; len_size])
851+
// Clear CRC bytes before length bytes so torn invalidation cannot create a new valid slot.
852+
blob.write_at(old_crc_offset, vec![0u8; crc_size])
851853
.await?;
852854
blob.sync().await?;
853855

856+
blob.write_at(old_slot_offset, vec![0u8; len_size]).await?;
857+
blob.sync().await?;
858+
854859
let final_record = if new_slot_start == 0 {
855860
Checksum {
856861
len1: new_len,

0 commit comments

Comments
 (0)