From 5fb77f28594fa8b96f55af9a0dd32252d4932b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=B0=E5=8F=8B?= Date: Mon, 4 Mar 2024 10:02:36 +0000 Subject: [PATCH] fix: bad read by wrong data region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User io may involve discontinuous segments in different chunks. Bad read is produced by merging them into continuous one. That is what Region does. This pr separate discontinuous segments into different regions, avoiding merging forcibly. Signed-off-by: 泰友 --- storage/src/cache/cachedfile.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/storage/src/cache/cachedfile.rs b/storage/src/cache/cachedfile.rs index 14f09905384..45f9a454ff6 100644 --- a/storage/src/cache/cachedfile.rs +++ b/storage/src/cache/cachedfile.rs @@ -1436,6 +1436,23 @@ impl FileIoMergeState { tag: BlobIoTag, chunk: Option>, ) -> Result<()> { + // Make sure user io of same region continuous + if !self.regions.is_empty() && self.joinable(region_type) { + let region = &self.regions[self.regions.len() - 1]; + if !region.seg.is_empty() && tag.is_user_io() { + if let BlobIoTag::User(ref seg) = tag { + println!("fucking {:x} {:x}", seg.offset as u64 + start, region.blob_address + region.seg.offset as u64 + region.seg.len as u64); + // Usually seg.offset = 0, for semantic integrity here. + if seg.offset as u64 + start + != region.blob_address + region.seg.offset as u64 + region.seg.len as u64 + { + // Stop append for non-continuous user io segment. + self.commit(); + } + } + } + } + if self.regions.is_empty() || !self.joinable(region_type) { self.regions.push(Region::new(region_type)); self.last_region_joinable = true; @@ -1564,7 +1581,7 @@ mod tests { let tag = BlobIoTag::User(BlobIoSegment { offset: 0x1800, - len: 0x1800, + len: 0x800, }); state .push(RegionType::CacheFast, 0x1000, 0x2000, tag, None) @@ -1581,8 +1598,8 @@ mod tests { assert_eq!(state.regions.len(), 1); let tag = BlobIoTag::User(BlobIoSegment { - offset: 0x0000, - len: 0x2000, + offset: 0x0001, + len: 0x1fff, }); state .push(RegionType::CacheSlow, 0x5000, 0x2000, tag, None)