sel4_async_block_io_fat/
block_io_wrapper.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7use core::convert::Infallible;
8use core::marker::PhantomData;
9
10use futures::future;
11
12use sel4_async_block_io::{
13    access::{Access, Witness},
14    constant_block_sizes, BlockIO, Operation,
15};
16
17pub use embedded_fat as fat;
18
19pub struct BlockIOWrapper<T, A> {
20    inner: T,
21    _phantom: PhantomData<A>,
22}
23
24impl<T, A> BlockIOWrapper<T, A> {
25    pub fn new(inner: T) -> Self {
26        Self {
27            inner,
28            _phantom: PhantomData,
29        }
30    }
31}
32
33impl<T: BlockIO<A, BlockSize = constant_block_sizes::BlockSize512>, A: Access> fat::BlockDevice
34    for BlockIOWrapper<T, A>
35{
36    type Error = Infallible;
37
38    async fn read(
39        &self,
40        blocks: &mut [fat::Block],
41        start_block_idx: fat::BlockIdx,
42        _reason: &str,
43    ) -> Result<(), Self::Error> {
44        future::join_all(blocks.iter_mut().enumerate().map(|(i, block)| async move {
45            let block_idx = u64::from(start_block_idx.0)
46                .checked_add(i.try_into().unwrap())
47                .unwrap();
48            self.inner
49                .read_or_write_blocks(
50                    block_idx,
51                    Operation::Read {
52                        buf: &mut block.contents,
53                        witness: A::ReadWitness::TRY_WITNESS.unwrap(),
54                    },
55                )
56                .await
57        }))
58        .await;
59        Ok(())
60    }
61
62    async fn write(
63        &self,
64        blocks: &[fat::Block],
65        start_block_idx: fat::BlockIdx,
66    ) -> Result<(), Self::Error> {
67        future::join_all(blocks.iter().enumerate().map(|(i, block)| async move {
68            let block_idx = u64::from(start_block_idx.0)
69                .checked_add(i.try_into().unwrap())
70                .unwrap();
71            self.inner
72                .read_or_write_blocks(
73                    block_idx,
74                    Operation::Write {
75                        buf: &block.contents,
76                        witness: A::WriteWitness::TRY_WITNESS.unwrap(),
77                    },
78                )
79                .await
80        }))
81        .await;
82        Ok(())
83    }
84
85    async fn num_blocks(&self) -> Result<fat::BlockCount, Self::Error> {
86        Ok(fat::BlockCount(self.inner.num_blocks().try_into().unwrap()))
87    }
88}