Skip to content

Commit

Permalink
Add layer 3-log: chunk, raw_log and tx_log
Browse files Browse the repository at this point in the history
  • Loading branch information
lucassong-mh authored and tatetian committed Dec 14, 2023
1 parent 1023b4b commit 64f76c2
Show file tree
Hide file tree
Showing 18 changed files with 2,344 additions and 982 deletions.
18 changes: 12 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@ pub enum Errno {
TxAborted,
/// Not found.
NotFound,
/// Invalid arguments.
InvalidArgs,
NoMemory,
IoError,
NotEnoughSpace,
/// Out of memory.
OutOfMemory,
/// Out of disk space.
OutOfDisk,
/// IO error.
IoFailed,
/// Permission denied.
PermissionDenied,
/// OS-specific unknown error.
OsSpecUnknown,
/// Encryption operation failed.
EncryptFault,
EncryptFailed,
/// Decryption operation failed.
DecryptFault,
DecryptFailed,
/// Not aligned to `BLOCK_SIZE`.
NonBlockAlignedSizeError,
NotBlockSizeAligned,
}

/// error used in this crate
Expand Down
10 changes: 8 additions & 2 deletions src/layers/0-bio/block_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ pub struct Buf(Pages);
impl Buf {
/// Allocate specific number of blocks as memory buffer.
pub fn alloc(num_blocks: usize) -> Result<Self> {
if num_blocks == 0 {
return_errno_with_msg!(
InvalidArgs,
"num_blocks must be greater than 0 for allocation"
)
}
let pages = Pages::alloc(num_blocks)?;
Ok(Self(pages))
}
Expand Down Expand Up @@ -89,7 +95,7 @@ impl<'a> TryFrom<&'a [u8]> for BufRef<'a> {

fn try_from(buf: &'a [u8]) -> Result<Self> {
if buf.len() % BLOCK_SIZE != 0 {
return_errno!(Errno::NonBlockAlignedSizeError);
return_errno!(Errno::NotBlockSizeAligned);
}
let new_self = Self(buf);
Ok(new_self)
Expand Down Expand Up @@ -137,7 +143,7 @@ impl<'a> TryFrom<&'a mut [u8]> for BufMut<'a> {

fn try_from(buf: &'a mut [u8]) -> Result<Self> {
if buf.len() % BLOCK_SIZE != 0 {
return_errno!(Errno::NonBlockAlignedSizeError);
return_errno!(Errno::NotBlockSizeAligned);
}
let new_self = Self(buf);
Ok(new_self)
Expand Down
1 change: 1 addition & 0 deletions src/layers/0-bio/block_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ impl_blockset_for!(Arc<T>, "(**self)", |this: &Arc<T>, range| {
/// A disk that impl `BlockSet`.
///
/// The `region` is the accessible subset.
#[derive(Clone)]
pub struct MemDisk {
disk: Arc<Mutex<Buf>>,
region: Range<BlockId>,
Expand Down
2 changes: 2 additions & 0 deletions src/layers/0-bio/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! The layer of untrusted block I/O.
use static_assertions::assert_eq_size;

mod block_buf;
Expand Down
8 changes: 4 additions & 4 deletions src/layers/1-crypto/crypto_blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<B: BlockSet> CryptoBlob<B> {
pub fn create(block_set: B, init_data: &[u8]) -> Result<Self> {
let capacity = block_set.nblocks() * BLOCK_SIZE - Self::HEADER_NBYTES;
if init_data.len() > capacity {
return_errno_with_msg!(NotEnoughSpace, "init_data is too large");
return_errno_with_msg!(OutOfDisk, "init_data is too large");
}
let nblocks = (Self::HEADER_NBYTES + init_data.len() + BLOCK_SIZE - 1) / BLOCK_SIZE;
let mut block_buf = Buf::alloc(nblocks)?;
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<B: BlockSet> CryptoBlob<B> {
/// known to an attacker.
pub fn write(&mut self, buf: &[u8]) -> Result<VersionId> {
if buf.len() > self.capacity() {
return_errno_with_msg!(NotEnoughSpace, "write data is too large");
return_errno_with_msg!(OutOfDisk, "write data is too large");
}
let nblocks = (Self::HEADER_NBYTES + buf.len() + BLOCK_SIZE - 1) / BLOCK_SIZE;
let mut block_buf = Buf::alloc(nblocks)?;
Expand Down Expand Up @@ -178,10 +178,10 @@ impl<B: BlockSet> CryptoBlob<B> {
}
};
if header.payload_len > self.capacity() {
return_errno_with_msg!(NotEnoughSpace, "payload_len is greater than the capacity");
return_errno_with_msg!(OutOfDisk, "payload_len is greater than the capacity");
}
if header.payload_len > buf.len() {
return_errno_with_msg!(NotEnoughSpace, "read_buf is too small");
return_errno_with_msg!(OutOfDisk, "read_buf is too small");
}
let nblock = (Self::HEADER_NBYTES + header.payload_len + BLOCK_SIZE - 1) / BLOCK_SIZE;
let mut block_buf = Buf::alloc(nblock)?;
Expand Down
7 changes: 2 additions & 5 deletions src/layers/1-crypto/crypto_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,7 @@ impl<L: BlockLog> CryptoChain<L> {

let payload_len = footer.len as usize;
if payload_len > Self::AVAIL_BLOCK_SIZE || payload_len > buf.len() {
return_errno_with_msg!(
NotEnoughSpace,
"wrong payload_len or the read_buf is too small"
);
return_errno_with_msg!(OutOfDisk, "wrong payload_len or the read_buf is too small");
}

// Check the footer MAC, to ensure the orderness and consecutiveness of blocks.
Expand Down Expand Up @@ -142,7 +139,7 @@ impl<L: BlockLog> CryptoChain<L> {
/// The confidentiality of the block is guaranteed.
pub fn append(&mut self, buf: &[u8]) -> Result<()> {
if buf.len() > Self::AVAIL_BLOCK_SIZE {
return_errno_with_msg!(NotEnoughSpace, "append data is too large");
return_errno_with_msg!(OutOfDisk, "append data is too large");
}
let mut block_buf = Buf::alloc(1)?;

Expand Down
2 changes: 1 addition & 1 deletion src/layers/1-crypto/crypto_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ impl<L: BlockLog> AppendDataBuf<L> {

pub fn append_data_nodes(&mut self, nodes: Vec<Arc<DataNode>>) -> Result<()> {
if self.is_full() {
return_errno_with_msg!(NoMemory, "cache out of capacity");
return_errno_with_msg!(OutOfMemory, "cache out of capacity");
}

self.node_queue.extend(nodes.into_iter());
Expand Down
14 changes: 8 additions & 6 deletions src/layers/2-edit/journal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub struct EditJournal<
/// The metadata of an edit journal.
///
/// The metadata is mainly useful when recovering an edit journal after a reboot.
#[repr(C)]
#[derive(Clone, Copy, Pod, Debug)]
pub struct EditJournalMeta {
/// The number of blocks reserved for storing a snapshot `CryptoBlob`.
pub snapshot_area_nblocks: usize,
Expand Down Expand Up @@ -357,14 +359,14 @@ where
CryptoBlob::<D>::HEADER_NBYTES + state_max_nbytes + Snapshot::<D>::meta_len();
let blob_blocks = (blob_bytes + BLOCK_SIZE - 1) / BLOCK_SIZE;
if 2 * blob_blocks >= disk.nblocks() {
return_errno_with_msg!(NotEnoughSpace, "the block_set for journal is too small");
return_errno_with_msg!(OutOfDisk, "the block_set for journal is too small");
};
let mut buf = Buf::alloc(blob_blocks)?;

// Serialize snapshot (state + metadata).
let snapshot = Snapshot::create(init_state.clone(), 0);
let serialized = postcard::to_slice(snapshot.as_ref(), buf.as_mut_slice())
.map_err(|_| Error::with_msg(NotEnoughSpace, "serialize snapshot failed"))?;
.map_err(|_| Error::with_msg(OutOfDisk, "serialize snapshot failed"))?;

// Persist snapshot to `CryptoBlob`.
let block_set0 = disk.subset(0..blob_blocks)?;
Expand Down Expand Up @@ -398,15 +400,15 @@ where
let snapshot0_res = match blob0.read(buf.as_mut_slice()) {
Ok(snapshot_len) => {
postcard::from_bytes::<Snapshot<S>>(&buf.as_slice()[..snapshot_len])
.map_err(|_| Error::with_msg(NotEnoughSpace, "deserialize snapshot0 failed"))
.map_err(|_| Error::with_msg(OutOfDisk, "deserialize snapshot0 failed"))
.map(|snapshot| Arc::new(snapshot))
}
Err(_) => Err(Error::with_msg(NotFound, "failed to read snapshot0")),
};
let snapshot1_res = match blob1.read(buf.as_mut_slice()) {
Ok(snapshot_len) => {
postcard::from_bytes::<Snapshot<S>>(&buf.as_slice()[..snapshot_len])
.map_err(|_| Error::with_msg(NotEnoughSpace, "deserialize snapshot1 failed"))
.map_err(|_| Error::with_msg(OutOfDisk, "deserialize snapshot1 failed"))
.map(|snapshot| Arc::new(snapshot))
}
Err(_) => Err(Error::with_msg(NotFound, "failed to read snapshot1")),
Expand Down Expand Up @@ -456,7 +458,7 @@ where
pub fn persist(&mut self, latest: Arc<Snapshot<S>>) -> Result<()> {
// Serialize the latest snapshot.
let buf = postcard::to_slice(latest.as_ref(), self.buf.as_mut_slice())
.map_err(|_| Error::with_msg(NotEnoughSpace, "serialize current state failed"))?;
.map_err(|_| Error::with_msg(OutOfDisk, "serialize current state failed"))?;

// Persist the latest snapshot to `CryptoBlob`.
let index = (self.latest_index + 1) % 2; // switch the `latest_index`
Expand Down Expand Up @@ -630,7 +632,7 @@ impl<E: Edit<S>, S: Sized> WriteBuf<E, S> {
e
);
}
return_errno_with_msg!(NotEnoughSpace, "no space for new Record in WriteBuf");
return_errno_with_msg!(OutOfDisk, "no space for new Record in WriteBuf");
}
}
}
Expand Down
Loading

0 comments on commit 64f76c2

Please sign in to comment.