Skip to content

Commit

Permalink
Add deleted flag in the header of chunk map file
Browse files Browse the repository at this point in the history
Signed-off-by: Qi Wang <[email protected]>
  • Loading branch information
yawqi committed Jun 29, 2022
1 parent 35f7166 commit 5f32d3b
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
4 changes: 4 additions & 0 deletions storage/src/cache/state/blob_state_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ where
any.downcast_ref::<BlobStateMap<IndexedChunkMap, u32>>()
.map(|v| v as &dyn RangeMap<I = u32>)
}

fn is_deleted(&self) -> bool {
self.c.is_deleted()
}
}

impl RangeMap for BlobStateMap<IndexedChunkMap, u32> {
Expand Down
18 changes: 16 additions & 2 deletions storage/src/cache/state/indexed_chunk_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,30 @@ const FILE_SUFFIX: &str = "chunk_map";
/// set_ready(3), the layout should be changed to [0b00010000, 0b00000000].
pub struct IndexedChunkMap {
map: PersistMap,
filename: String,
}

impl IndexedChunkMap {
/// Create a new instance of `IndexedChunkMap`.
pub fn new(blob_path: &str, chunk_count: u32, persist: bool) -> Result<Self> {
let filename = format!("{}.{}", blob_path, FILE_SUFFIX);

PersistMap::open(&filename, chunk_count, true, persist).map(|map| IndexedChunkMap { map })
PersistMap::open(&filename, chunk_count, true, persist)
.map(|map| IndexedChunkMap { map, filename })
}

/// Create a new instance of `IndexedChunkMap` from an existing chunk map file.
pub fn open(blob_info: &BlobInfo, workdir: &str) -> Result<Self> {
let filename = format!("{}/{}.{}", workdir, blob_info.blob_id(), FILE_SUFFIX);

PersistMap::open(&filename, blob_info.chunk_count(), false, true)
.map(|map| IndexedChunkMap { map })
.map(|map| IndexedChunkMap { map, filename })
}

pub fn remove(self) -> Result<()> {
self.map.mark_deleted();
std::fs::remove_file(self.filename)?;
Ok(())
}
}

Expand All @@ -70,6 +78,10 @@ impl ChunkMap for IndexedChunkMap {
fn as_range_map(&self) -> Option<&dyn RangeMap<I = u32>> {
Some(self)
}

fn is_deleted(&self) -> bool {
self.map.is_file_deleted()
}
}

impl RangeMap for IndexedChunkMap {
Expand Down Expand Up @@ -279,6 +291,7 @@ mod tests {
version: 1,
magic2: MAGIC2,
all_ready: MAGIC_ALL_READY,
deleted: 0,
reserved: [0x0u8; HEADER_RESERVED_SIZE],
};

Expand Down Expand Up @@ -324,6 +337,7 @@ mod tests {
version: 0,
magic2: 0,
all_ready: 0,
deleted: 0,
reserved: [0x0u8; HEADER_RESERVED_SIZE],
};

Expand Down
5 changes: 5 additions & 0 deletions storage/src/cache/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ pub trait ChunkMap: Any + Send + Sync {
fn as_range_map(&self) -> Option<&dyn RangeMap<I = u32>> {
None
}

/// Check whether the on-disk file is deleted.
fn is_deleted(&self) -> bool {
false
}
}

/// Trait to track chunk or data readiness state.
Expand Down
40 changes: 39 additions & 1 deletion storage/src/cache/state/persist_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::cell::Cell;
use std::ffi::c_void;
use std::fs::{File, OpenOptions};
use std::io::{Result, Write};
Expand All @@ -16,8 +17,9 @@ use crate::utils::readahead;
pub(crate) const MAGIC1: u32 = 0x424D_4150;
pub(crate) const MAGIC2: u32 = 0x434D_4150;
pub(crate) const MAGIC_ALL_READY: u32 = 0x4D4D_4150;
pub(crate) const MAGIC_DELETED: u32 = 0x4E4D_4150;
pub(crate) const HEADER_SIZE: usize = 4096;
pub(crate) const HEADER_RESERVED_SIZE: usize = HEADER_SIZE - 16;
pub(crate) const HEADER_RESERVED_SIZE: usize = HEADER_SIZE - 20;

/// The blob chunk map file header, 4096 bytes.
#[repr(C)]
Expand All @@ -27,6 +29,7 @@ pub(crate) struct Header {
pub version: u32,
pub magic2: u32,
pub all_ready: u32,
pub deleted: u32,
pub reserved: [u8; HEADER_RESERVED_SIZE],
}

Expand All @@ -46,6 +49,7 @@ pub(crate) struct PersistMap {
pub size: usize,
pub base: *const u8,
pub not_ready_count: AtomicU32,
pub is_deleted: Cell<bool>,
}

impl PersistMap {
Expand Down Expand Up @@ -167,6 +171,7 @@ impl PersistMap {
size: expected_size as usize,
base: base as *const u8,
not_ready_count: AtomicU32::new(not_ready_count),
is_deleted: Cell::new(false),
})
}

Expand All @@ -176,6 +181,7 @@ impl PersistMap {
version: 1,
magic2: MAGIC2,
all_ready: 0,
deleted: 0,
reserved: [0x0u8; HEADER_RESERVED_SIZE],
};

Expand Down Expand Up @@ -268,6 +274,38 @@ impl PersistMap {
}
}

pub fn is_file_deleted(&self) -> bool {
if self.is_deleted.get() {
return true;
}
let base = self.base as *const c_void as *mut c_void;
unsafe {
if libc::msync(base, self.size, libc::MS_SYNC) == 0 {
let header = &mut *(self.base as *mut Header);
if header.deleted == MAGIC_DELETED {
self.is_deleted.set(true);
return true;
}
}
}
false
}

pub fn mark_deleted(&self) {
if self.is_file_deleted() {
return;
}
let base = self.base as *const c_void as *mut c_void;
unsafe {
if libc::msync(base, self.size, libc::MS_SYNC) == 0 {
let header = &mut *(self.base as *mut Header);
header.deleted = MAGIC_DELETED;
self.is_deleted.set(true);
let _ = libc::msync(base, HEADER_SIZE, libc::MS_SYNC);
}
}
}

#[inline]
pub fn is_range_all_ready(&self) -> bool {
self.not_ready_count.load(Ordering::Acquire) == 0
Expand Down

0 comments on commit 5f32d3b

Please sign in to comment.