implementing TreeItem and parsing for extentdata
- implementing extentdata as an enum of either Inline + data bytes or not inline (preallocated and whatever) - accessor for name component in ItemWithName<T>
This commit is contained in:
parent
5a9918285f
commit
6148e1b089
|
@ -229,8 +229,29 @@ macro_rules! impl_parse_try_from_ctx {
|
|||
};
|
||||
}
|
||||
|
||||
impl_parse_try_from_ctx!(Chunk, Header, Key, RootItem, INodeItem, INodeRef, DirItem);
|
||||
impl_try_from_ctx!(Key, Chunk, Header, Superblock, RootItem, INodeItem, INodeRef, DirItem);
|
||||
impl_parse_try_from_ctx!(
|
||||
Chunk,
|
||||
Header,
|
||||
Key,
|
||||
RootItem,
|
||||
INodeItem,
|
||||
INodeRef,
|
||||
DirItem,
|
||||
ExtentData1,
|
||||
ExtentData2
|
||||
);
|
||||
impl_try_from_ctx!(
|
||||
Key,
|
||||
Chunk,
|
||||
Header,
|
||||
Superblock,
|
||||
RootItem,
|
||||
INodeItem,
|
||||
INodeRef,
|
||||
DirItem,
|
||||
ExtentData1,
|
||||
ExtentData2
|
||||
);
|
||||
|
||||
const MAX_LABEL_SIZE: usize = 0x100;
|
||||
const SYS_CHUNK_ARRAY_SIZE: usize = 0x800;
|
||||
|
@ -294,31 +315,71 @@ pub struct ChunkItemStripe {
|
|||
dev_uuid: Uuid,
|
||||
}
|
||||
|
||||
#[repr(C, packed(1))]
|
||||
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||
pub struct ExtentData {
|
||||
generation: u64,
|
||||
decoded_size: u64,
|
||||
compression: u8,
|
||||
encryption: u8,
|
||||
encoding: u16,
|
||||
ty: u8,
|
||||
data: [u8; 1],
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ExtentDataType {
|
||||
Inline,
|
||||
Regular,
|
||||
PreAlloc,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ExtentData {
|
||||
Inline { header: ExtentData1, data: Vec<u8> },
|
||||
Other(ExtentData2),
|
||||
}
|
||||
|
||||
impl Parseable for ExtentData {
|
||||
fn parse(bytes: &[u8]) -> Result<Self> {
|
||||
let header = ExtentData1::parse(bytes)?;
|
||||
|
||||
let extent = match header.ty() {
|
||||
ExtentDataType::Inline => {
|
||||
let data = bytes[size_of::<ExtentData1>()..].to_vec();
|
||||
Self::Inline { header, data }
|
||||
}
|
||||
_ => Self::Other(ExtentData2::parse(bytes)?),
|
||||
};
|
||||
|
||||
Ok(extent)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C, packed(1))]
|
||||
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||
#[derive(Debug, Clone, Copy, FromBytes, AsBytes)]
|
||||
pub struct ExtentData1 {
|
||||
generation: U64<LE>,
|
||||
decoded_size: U64<LE>,
|
||||
compression: u8,
|
||||
encryption: u8,
|
||||
encoding: U16<LE>,
|
||||
ty: u8,
|
||||
}
|
||||
|
||||
impl ExtentData1 {
|
||||
pub fn ty(&self) -> ExtentDataType {
|
||||
match self.ty {
|
||||
0 => ExtentDataType::Inline,
|
||||
1 => ExtentDataType::Regular,
|
||||
2 => ExtentDataType::PreAlloc,
|
||||
_ => panic!("extentdatatype of invalid"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C, packed(1))]
|
||||
#[derive(Debug, Clone, Copy, FromBytes, AsBytes)]
|
||||
pub struct ExtentData2 {
|
||||
address: u64,
|
||||
size: u64,
|
||||
offset: u64,
|
||||
num_bytes: u64,
|
||||
header: ExtentData1,
|
||||
address: U64<LE>,
|
||||
size: U64<LE>,
|
||||
offset: U64<LE>,
|
||||
num_bytes: U64<LE>,
|
||||
}
|
||||
|
||||
#[repr(C, packed(1))]
|
||||
#[derive(Debug, Clone, Copy, FromBytes, AsBytes)]
|
||||
pub struct INodeRef {
|
||||
index: U64<LE>,
|
||||
pub index: U64<LE>,
|
||||
name_len: U16<LE>,
|
||||
}
|
||||
|
||||
|
@ -878,6 +939,11 @@ where
|
|||
pub fn item(&self) -> &I {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &Vec<u8> {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn name_as_str(&self) -> core::result::Result<&str, core::str::Utf8Error> {
|
||||
core::str::from_utf8(&self.name)
|
||||
}
|
||||
|
@ -907,8 +973,10 @@ pub struct InodeRef {
|
|||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy, FromBytes, AsBytes)]
|
||||
#[derive(Derivative, Clone, PartialEq, Eq, Copy, FromBytes, AsBytes)]
|
||||
#[derivative(Debug)]
|
||||
pub struct Header {
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub csum: [u8; 32],
|
||||
pub fsid: Uuid,
|
||||
/// Which block this node is supposed to live in
|
||||
|
@ -946,6 +1014,7 @@ use alloc::vec::Vec;
|
|||
pub enum TreeItem {
|
||||
Chunk(Chunk),
|
||||
Root(RootItem),
|
||||
ExtentData(ExtentData),
|
||||
DirItem(Vec<DirItemEntry>),
|
||||
DirIndex(DirItemEntry),
|
||||
INodeItem(INodeItem),
|
||||
|
@ -989,6 +1058,12 @@ impl From<INodeRefEntry> for TreeItem {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ExtentData> for TreeItem {
|
||||
fn from(value: ExtentData) -> Self {
|
||||
Self::ExtentData(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeItem {
|
||||
pub fn parse(item: &Item, bytes: &[u8]) -> Result<Self> {
|
||||
Ok(match item.key.ty() {
|
||||
|
@ -998,20 +1073,13 @@ impl TreeItem {
|
|||
ObjectType::DirIndex => DirItemEntry::parse(bytes)?.into(),
|
||||
ObjectType::INodeItem => INodeItem::parse(bytes)?.into(),
|
||||
ObjectType::INodeRef => INodeRefEntry::parse(bytes)?.into(),
|
||||
ObjectType::ExtentData => ExtentData::parse(bytes)?.into(),
|
||||
_ => TreeItem::Unimplemented,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_dir_item(&self) -> Option<&Vec<DirItemEntry>> {
|
||||
if let Self::DirItem(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_dir_index(&self) -> Option<&DirItemEntry> {
|
||||
if let Self::DirIndex(v) = self {
|
||||
pub fn as_extent_data(&self) -> Option<&ExtentData> {
|
||||
if let Self::ExtentData(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
|
@ -1035,6 +1103,38 @@ impl TreeItem {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_dir_item(&self) -> Option<&Vec<DirItemEntry>> {
|
||||
if let Self::DirItem(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_dir_index(&self) -> Option<&DirItemEntry> {
|
||||
if let Self::DirIndex(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_inode_ref(&self) -> Option<&INodeRefEntry> {
|
||||
if let Self::INodeRef(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_inode_item(&self) -> Option<&INodeItem> {
|
||||
if let Self::INodeItem(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
Loading…
Reference in a new issue