diff --git a/README.md b/README.md index 3ca36a6..c9ef33f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ erofs-cli inspect -i http://example.com/images/system.erofs cat /etc/os-release ### TODO - [ ] Extended attributes -- [ ] Compressed data (lz4, lzma, deflate) +- [-] Compressed data (lz4, lzma, deflate) - [ ] Image building (`mkfs.erofs` equivalent) ## License diff --git a/erofs/src/decomp/mod.rs b/erofs/src/decomp/mod.rs new file mode 100644 index 0000000..b0bff43 --- /dev/null +++ b/erofs/src/decomp/mod.rs @@ -0,0 +1,36 @@ +//! Basic Z_EROFS decompression support. +//! +//! This roughly follows parts of the Linux kernel implementation +//! (fs/erofs/zmap.c, zdata.c), but is not a 1:1 port. +//! +//! The idea is: +//! 1. VLE index maps logical clusters +//! 2. pclusters - contain compressed data +//! 3. decompression - handled via lz4/lzma/deflate (not implemented here yet) +//! +//! Some details are still incomplete. + +#[derive(Debug, Clone, Copy)] +pub struct VLEIndex { + pub advise: u16, // compression hints (di_advise) + pub cluster_offset: u16, // offset within the decompressed cluster + pub block_addr: u32, // physical block (only meaningful for HEAD entries) +} + +impl VLEIndex { + /// Read a VLE index from raw bytes. + /// Expects at least 8 bytes (little-endian layout). + pub fn from_bytes(data: &[u8]) -> crate::Result { + if data.len() < 8 { + return Err(crate::Error::NotSupported( + "VLE index too short".into() + )); + } + + Ok(Self { + advise: u16::from_le_bytes([data[0], data[1]]), + cluster_offset: u16::from_le_bytes([data[2], data[3]]), + block_addr: u32::from_le_bytes([data[4], data[5], data[6], data[7]]), + }) + } +} \ No newline at end of file diff --git a/erofs/src/filesystem.rs b/erofs/src/filesystem.rs index dfe22aa..f347b7e 100644 --- a/erofs/src/filesystem.rs +++ b/erofs/src/filesystem.rs @@ -125,6 +125,8 @@ impl EroFSCore { Ok(BlockPlan::Direct { offset, size: len }) } Layout::CompressedFull | Layout::CompressedCompact => { + // TODO: Implement VLE index parsing and pcluster decompression + // See: decomp module, kernel fs/erofs/zmap.c + zdata.c Err(Error::NotSupported("compressed compact layout".to_string())) } Layout::ChunkBased => { diff --git a/erofs/src/lib.rs b/erofs/src/lib.rs index 368b65e..3c05b0f 100644 --- a/erofs/src/lib.rs +++ b/erofs/src/lib.rs @@ -53,6 +53,7 @@ extern crate std; pub(crate) mod dirent; pub(crate) mod filesystem; +pub(crate) mod decomp; pub mod r#async; pub mod backend;