Skip to content

Commit 16a676d

Browse files
copilot nits
1 parent 8768b5d commit 16a676d

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

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

Lines changed: 19 additions & 16 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,34 +822,36 @@ 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())
826-
.await?;
829+
blob.write_at(new_slot_offset, staged_slot.to_vec()).await?;
827830
blob.sync().await?;
828831

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

836836
let old_slot_start = if new_slot_start == 0 {
837837
CHECKSUM_SLOT_SIZE
838838
} else {
839839
0
840840
};
841+
let old_slot_offset = crc_start
842+
.checked_add(old_slot_start as u64)
843+
.ok_or(Error::OffsetOverflow)?;
841844
let len_size = std::mem::size_of::<u16>();
842845
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?;
846+
let old_crc_offset = old_slot_offset
847+
.checked_add(len_size as u64)
848+
.ok_or(Error::OffsetOverflow)?;
849+
850+
// Clear CRC bytes before length bytes so torn invalidation cannot create a new valid slot.
851+
blob.write_at(old_crc_offset, vec![0u8; crc_size]).await?;
848852
blob.sync().await?;
849853

850-
blob.write_at(crc_start + old_slot_start as u64, vec![0u8; len_size])
851-
.await?;
854+
blob.write_at(old_slot_offset, vec![0u8; len_size]).await?;
852855
blob.sync().await?;
853856

854857
let final_record = if new_slot_start == 0 {

0 commit comments

Comments
 (0)