Message ID | 20240916135634.98554-11-toolmanp@tlmp.cc (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | erofs: introduce Rust implementation | expand |
Yiyang Wu via Linux-erofs <linux-erofs@lists.ozlabs.org> 于2024年9月16日周一 21:57写道: > > Add device_infos implementation in rust. It will later be used > to be put inside the SuperblockInfo. This mask and spec can later > be used to chunk-based image file block mapping. > > Signed-off-by: Yiyang Wu <toolmanp@tlmp.cc> > --- > fs/erofs/rust/erofs_sys/devices.rs | 47 ++++++++++++++++++++++++++++++ > 1 file changed, 47 insertions(+) > > diff --git a/fs/erofs/rust/erofs_sys/devices.rs b/fs/erofs/rust/erofs_sys/devices.rs > index 097676ee8720..7495164c7bd0 100644 > --- a/fs/erofs/rust/erofs_sys/devices.rs > +++ b/fs/erofs/rust/erofs_sys/devices.rs > @@ -1,6 +1,10 @@ > // Copyright 2024 Yiyang Wu > // SPDX-License-Identifier: MIT or GPL-2.0-or-later > > +use super::alloc_helper::*; > +use super::data::raw_iters::*; > +use super::data::*; > +use super::*; > use alloc::vec::Vec; > > /// Device specification. > @@ -21,8 +25,51 @@ pub(crate) struct DeviceSlot { > reserved: [u8; 56], > } > > +impl From<[u8; 128]> for DeviceSlot { > + fn from(data: [u8; 128]) -> Self { > + Self { > + tags: data[0..64].try_into().unwrap(), > + blocks: u32::from_le_bytes([data[64], data[65], data[66], data[67]]), > + mapped_blocks: u32::from_le_bytes([data[68], data[69], data[70], data[71]]), > + reserved: data[72..128].try_into().unwrap(), > + } > + } > +} > + > /// Device information. > pub(crate) struct DeviceInfo { > pub(crate) mask: u16, > pub(crate) specs: Vec<DeviceSpec>, > } > + > +pub(crate) fn get_device_infos<'a>( > + iter: &mut (dyn ContinuousBufferIter<'a> + 'a), > +) -> PosixResult<DeviceInfo> { > + let mut specs = Vec::new(); > + for data in iter { > + let buffer = data?; > + let mut cur: usize = 0; > + let len = buffer.content().len(); > + while cur + 128 <= len { It is better to use macros instead of hardcode, like: const EROFS_DEVT_SLOT_SIZE: usize = size_of::<DeviceSlot>(); Also works to the other similar usages in this patch set. Thanks, Jianan > > + let slot_data: [u8; 128] = buffer.content()[cur..cur + 128].try_into().unwrap(); > + let slot = DeviceSlot::from(slot_data); > + cur += 128; > + push_vec( > + &mut specs, > + DeviceSpec { > + tags: slot.tags, > + blocks: slot.blocks, > + mapped_blocks: slot.mapped_blocks, > + }, > + )?; > + } > + } > + > + let mask = if specs.is_empty() { > + 0 > + } else { > + (1 << (specs.len().ilog2() + 1)) - 1 > + }; > + > + Ok(DeviceInfo { mask, specs }) > +} > -- > 2.46.0 >
diff --git a/fs/erofs/rust/erofs_sys/devices.rs b/fs/erofs/rust/erofs_sys/devices.rs index 097676ee8720..7495164c7bd0 100644 --- a/fs/erofs/rust/erofs_sys/devices.rs +++ b/fs/erofs/rust/erofs_sys/devices.rs @@ -1,6 +1,10 @@ // Copyright 2024 Yiyang Wu // SPDX-License-Identifier: MIT or GPL-2.0-or-later +use super::alloc_helper::*; +use super::data::raw_iters::*; +use super::data::*; +use super::*; use alloc::vec::Vec; /// Device specification. @@ -21,8 +25,51 @@ pub(crate) struct DeviceSlot { reserved: [u8; 56], } +impl From<[u8; 128]> for DeviceSlot { + fn from(data: [u8; 128]) -> Self { + Self { + tags: data[0..64].try_into().unwrap(), + blocks: u32::from_le_bytes([data[64], data[65], data[66], data[67]]), + mapped_blocks: u32::from_le_bytes([data[68], data[69], data[70], data[71]]), + reserved: data[72..128].try_into().unwrap(), + } + } +} + /// Device information. pub(crate) struct DeviceInfo { pub(crate) mask: u16, pub(crate) specs: Vec<DeviceSpec>, } + +pub(crate) fn get_device_infos<'a>( + iter: &mut (dyn ContinuousBufferIter<'a> + 'a), +) -> PosixResult<DeviceInfo> { + let mut specs = Vec::new(); + for data in iter { + let buffer = data?; + let mut cur: usize = 0; + let len = buffer.content().len(); + while cur + 128 <= len { + let slot_data: [u8; 128] = buffer.content()[cur..cur + 128].try_into().unwrap(); + let slot = DeviceSlot::from(slot_data); + cur += 128; + push_vec( + &mut specs, + DeviceSpec { + tags: slot.tags, + blocks: slot.blocks, + mapped_blocks: slot.mapped_blocks, + }, + )?; + } + } + + let mask = if specs.is_empty() { + 0 + } else { + (1 << (specs.len().ilog2() + 1)) - 1 + }; + + Ok(DeviceInfo { mask, specs }) +}
Add device_infos implementation in rust. It will later be used to be put inside the SuperblockInfo. This mask and spec can later be used to chunk-based image file block mapping. Signed-off-by: Yiyang Wu <toolmanp@tlmp.cc> --- fs/erofs/rust/erofs_sys/devices.rs | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)