This patch adds a special iterator that is capable of iterating over a memory region in the granularity of a common page. This can be later used to read device buffer or fast symlink. Signed-off-by: Yiyang Wu <toolmanp@xxxxxxx> --- fs/erofs/rust/erofs_sys/data.rs | 2 + fs/erofs/rust/erofs_sys/data/raw_iters.rs | 6 ++ .../rust/erofs_sys/data/raw_iters/ref_iter.rs | 68 +++++++++++++++++++ .../rust/erofs_sys/data/raw_iters/traits.rs | 13 ++++ 4 files changed, 89 insertions(+) create mode 100644 fs/erofs/rust/erofs_sys/data/raw_iters.rs create mode 100644 fs/erofs/rust/erofs_sys/data/raw_iters/ref_iter.rs create mode 100644 fs/erofs/rust/erofs_sys/data/raw_iters/traits.rs diff --git a/fs/erofs/rust/erofs_sys/data.rs b/fs/erofs/rust/erofs_sys/data.rs index 284c8b1f3bd4..483f3204ce42 100644 --- a/fs/erofs/rust/erofs_sys/data.rs +++ b/fs/erofs/rust/erofs_sys/data.rs @@ -1,6 +1,8 @@ // Copyright 2024 Yiyang Wu // SPDX-License-Identifier: MIT or GPL-2.0-or-later pub(crate) mod backends; +pub(crate) mod raw_iters; +use super::superblock::*; use super::*; /// Represent some sort of generic data source. This cound be file, memory or even network. diff --git a/fs/erofs/rust/erofs_sys/data/raw_iters.rs b/fs/erofs/rust/erofs_sys/data/raw_iters.rs new file mode 100644 index 000000000000..8f3bd250d252 --- /dev/null +++ b/fs/erofs/rust/erofs_sys/data/raw_iters.rs @@ -0,0 +1,6 @@ +// Copyright 2024 Yiyang Wu +// SPDX-License-Identifier: MIT or GPL-2.0-or-later + +pub(crate) mod ref_iter; +mod traits; +pub(crate) use traits::*; diff --git a/fs/erofs/rust/erofs_sys/data/raw_iters/ref_iter.rs b/fs/erofs/rust/erofs_sys/data/raw_iters/ref_iter.rs new file mode 100644 index 000000000000..5aa2b7f44f3d --- /dev/null +++ b/fs/erofs/rust/erofs_sys/data/raw_iters/ref_iter.rs @@ -0,0 +1,68 @@ +// Copyright 2024 Yiyang Wu +// SPDX-License-Identifier: MIT or GPL-2.0-or-later + +use super::super::*; +use super::*; + +/// Continous Ref Buffer Iterator which iterates over a range of disk addresses within the +/// the temp block size. Since the temp block is always the same size as page and it will not +/// overflow. +pub(crate) struct ContinuousRefIter<'a, B> +where + B: Backend, +{ + sb: &'a SuperBlock, + backend: &'a B, + offset: Off, + len: Off, +} + +impl<'a, B> ContinuousRefIter<'a, B> +where + B: Backend, +{ + pub(crate) fn new(sb: &'a SuperBlock, backend: &'a B, offset: Off, len: Off) -> Self { + Self { + sb, + backend, + offset, + len, + } + } +} + +impl<'a, B> Iterator for ContinuousRefIter<'a, B> +where + B: Backend, +{ + type Item = PosixResult<RefBuffer<'a>>; + fn next(&mut self) -> Option<Self::Item> { + if self.len == 0 { + return None; + } + let accessor = self.sb.blk_access(self.offset); + let len = accessor.len.min(self.len); + let result: Option<Self::Item> = self.backend.as_buf(self.offset, len).map_or_else( + |e| Some(Err(e)), + |buf| { + self.offset += len; + self.len -= len; + Some(Ok(buf)) + }, + ); + result + } +} + +impl<'a, B> ContinuousBufferIter<'a> for ContinuousRefIter<'a, B> +where + B: Backend, +{ + fn advance_off(&mut self, offset: Off) { + self.offset += offset; + self.len -= offset + } + fn eof(&self) -> bool { + self.len == 0 + } +} diff --git a/fs/erofs/rust/erofs_sys/data/raw_iters/traits.rs b/fs/erofs/rust/erofs_sys/data/raw_iters/traits.rs new file mode 100644 index 000000000000..90b6a51658a9 --- /dev/null +++ b/fs/erofs/rust/erofs_sys/data/raw_iters/traits.rs @@ -0,0 +1,13 @@ +// Copyright 2024 Yiyang Wu +// SPDX-License-Identifier: MIT or GPL-2.0-or-later + +use super::super::*; + +/// Represents a basic iterator over a range of bytes from data backends. +/// Note that this is skippable and can be used to move the iterator's cursor forward. +pub(crate) trait ContinuousBufferIter<'a>: + Iterator<Item = PosixResult<RefBuffer<'a>>> +{ + fn advance_off(&mut self, offset: Off); + fn eof(&self) -> bool; +} -- 2.46.0