@@ -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.
new file mode 100644
@@ -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::*;
new file mode 100644
@@ -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
+ }
+}
new file mode 100644
@@ -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;
+}
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@tlmp.cc> --- 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