Skip to content

Commit

Permalink
Add Free and Unknown object types
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Jun 21, 2023
1 parent cdd260e commit 355c4c0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 30 deletions.
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ where
let mut objects = block.objects();
while let Some(meta_object) = objects.next(&mut self.medium).await? {
match meta_object.state() {
ObjectState::Free => break,
ObjectState::Free | ObjectState::Corrupted => break,
ObjectState::Allocated => break,
ObjectState::Finalized => {}
ObjectState::Deleted => continue,
Expand Down Expand Up @@ -826,8 +826,8 @@ trait ObjectMover: Debug {
while let Some(object) = iter.next(&mut storage.medium).await? {
match object.state() {
ObjectState::Free | ObjectState::Deleted => continue,
ObjectState::Allocated => {
log::warn!("Encountered an allocated object");
ObjectState::Allocated | ObjectState::Corrupted => {
log::warn!("Encountered object in incorrect state");
// TODO: retry in a different object
return Err(StorageError::InsufficientSpace);
}
Expand Down
1 change: 1 addition & 0 deletions src/ll/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ impl<M: StorageMedium> IndexedBlockInfo<M> {
match object.state() {
ObjectState::Allocated | ObjectState::Deleted => deleted += object.total_size(),
ObjectState::Free | ObjectState::Finalized => {}
ObjectState::Corrupted => break,
}
}

Expand Down
57 changes: 30 additions & 27 deletions src/ll/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ use crate::{
// Do not use 0xFF as it is reserved for the free state.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ObjectType {
Free = 0xFF,
FileMetadata = 0x8F,
FileData = 0x8E,
Unknown = 0x00,
}

impl ObjectType {
fn parse(byte: u8) -> Option<Self> {
fn parse(byte: u8) -> Self {
match byte {
v if v == Self::FileMetadata as u8 => Some(Self::FileMetadata),
v if v == Self::FileData as u8 => Some(Self::FileData),
_ => None,
v if v == Self::FileMetadata as u8 => Self::FileMetadata,
v if v == Self::FileData as u8 => Self::FileData,
0xFF => Self::Free,
_ => Self::Unknown,
}
}
}
Expand All @@ -29,31 +32,32 @@ pub enum ObjectDataState {
Untrusted = 0xFF,
Valid = 0xF0,
Deleted = 0x00,
Unknown,
}

impl ObjectDataState {
fn parse(byte: u8) -> Result<Self, StorageError> {
fn parse(byte: u8) -> Self {
match byte {
v if v == Self::Untrusted as u8 => Ok(Self::Untrusted),
v if v == Self::Valid as u8 => Ok(Self::Valid),
v if v == Self::Deleted as u8 => Ok(Self::Deleted),
v if v == Self::Untrusted as u8 => Self::Untrusted,
v if v == Self::Valid as u8 => Self::Valid,
v if v == Self::Deleted as u8 => Self::Deleted,
_ => {
log::warn!("Unknown object data state: 0x{byte:02X}");
Err(StorageError::FsCorrupted)
Self::Unknown
}
}
}

fn parse_pair(finalized_byte: u8, deleted_byte: u8) -> Result<Self, StorageError> {
fn parse_pair(finalized_byte: u8, deleted_byte: u8) -> Self {
match (finalized_byte, deleted_byte) {
(0xFF, 0xFF) => Ok(Self::Untrusted),
(0x00, 0xFF) => Ok(Self::Valid),
(0x00, 0x00) => Ok(Self::Deleted),
(0xFF, 0xFF) => Self::Untrusted,
(0x00, 0xFF) => Self::Valid,
(0x00, 0x00) => Self::Deleted,
_ => {
log::warn!(
"Unknown object data state: (0x{finalized_byte:02X}, 0x{deleted_byte:02X})"
);
Err(StorageError::FsCorrupted)
Self::Unknown
}
}
}
Expand All @@ -73,6 +77,7 @@ impl From<CompositeObjectState> for ObjectState {
ObjectDataState::Untrusted => Self::Allocated,
ObjectDataState::Valid => Self::Finalized,
ObjectDataState::Deleted => Self::Deleted,
ObjectDataState::Unknown => Self::Corrupted,
},
}
}
Expand Down Expand Up @@ -101,7 +106,9 @@ impl CompositeObjectState {
}

let new_data_state = match new_state {
ObjectState::Free => unreachable!(),
ObjectState::Free | ObjectState::Corrupted => {
unreachable!()
}
ObjectState::Allocated => ObjectDataState::Untrusted,
ObjectState::Finalized => ObjectDataState::Valid,
ObjectState::Deleted => ObjectDataState::Deleted,
Expand Down Expand Up @@ -130,21 +137,17 @@ impl CompositeObjectState {
medium.read(location.block, location.offset, buffer).await?;

match ObjectType::parse(buffer[0]) {
Some(ty) => {
ObjectType::Free => Ok(Self::Free),
ty => {
let data_state = match M::WRITE_GRANULARITY {
WriteGranularity::Bit => ObjectDataState::parse(buffer[1])?,
WriteGranularity::Bit => ObjectDataState::parse(buffer[1]),
WriteGranularity::Word(w) => {
ObjectDataState::parse_pair(buffer[w], buffer[2 * w])?
ObjectDataState::parse_pair(buffer[w], buffer[2 * w])
}
};

Ok(Self::Allocated(ty, data_state))
}
None if buffer[0] == 0xFF => Ok(Self::Free),
None => {
log::warn!("Unknown object type: 0x{:02X}", buffer[0]);
Err(StorageError::FsCorrupted)
}
}
}

Expand Down Expand Up @@ -223,6 +226,7 @@ pub enum ObjectState {
Allocated,
Finalized,
Deleted,
Corrupted,
}

impl ObjectState {
Expand Down Expand Up @@ -360,8 +364,6 @@ impl ObjectHeader {
medium: &mut M,
state: ObjectState,
) -> Result<(), StorageError> {
debug_assert!(!state.is_free());

log::trace!("ObjectHeader::update_state({:?}, {state:?})", self.location);

if state == self.state.into() {
Expand All @@ -381,8 +383,9 @@ impl ObjectHeader {
.delete(medium, self.location, object_type)
.await?
}
ObjectState::Allocated => return Err(StorageError::InvalidOperation),
ObjectState::Free => unreachable!(),
ObjectState::Free | ObjectState::Corrupted | ObjectState::Allocated => {
return Err(StorageError::InvalidOperation);
}
};

Ok(())
Expand Down

0 comments on commit 355c4c0

Please sign in to comment.