Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add layer 3-log #11

Merged
merged 1 commit into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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