@@ -16,40 +16,6 @@ pub struct Block {
1616 pub contents : [ u8 ; Block :: LEN ] ,
1717}
1818
19- /// The linear numeric address of a block (or sector).
20- ///
21- /// The first block on a disk gets `BlockIdx(0)` (which usually contains the
22- /// Master Boot Record).
23- #[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
24- #[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
25- pub struct BlockIdx ( pub u32 ) ;
26-
27- /// The a number of blocks (or sectors).
28- ///
29- /// Add this to a `BlockIdx` to get an actual address on disk.
30- #[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
31- #[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
32- pub struct BlockCount ( pub u32 ) ;
33-
34- /// An iterator returned from `Block::range`.
35- pub struct BlockIter {
36- inclusive_end : BlockIdx ,
37- current : BlockIdx ,
38- }
39-
40- /// A block device - a device which can read and write blocks (or
41- /// sectors). Only supports devices which are <= 2 TiB in size.
42- pub trait BlockDevice {
43- /// The errors that the `BlockDevice` can return. Must be debug formattable.
44- type Error : core:: fmt:: Debug ;
45- /// Read one or more blocks, starting at the given block index.
46- fn read ( & self , blocks : & mut [ Block ] , start_block_idx : BlockIdx ) -> Result < ( ) , Self :: Error > ;
47- /// Write one or more blocks, starting at the given block index.
48- fn write ( & self , blocks : & [ Block ] , start_block_idx : BlockIdx ) -> Result < ( ) , Self :: Error > ;
49- /// Determine how many blocks this device can hold.
50- fn num_blocks ( & self ) -> Result < BlockCount , Self :: Error > ;
51- }
52-
5319impl Block {
5420 /// All our blocks are a fixed length of 512 bytes. We do not support
5521 /// 'Advanced Format' Hard Drives with 4 KiB blocks, nor weird old
@@ -67,64 +33,6 @@ impl Block {
6733 }
6834}
6935
70- impl Default for Block {
71- fn default ( ) -> Self {
72- Self :: new ( )
73- }
74- }
75-
76- impl core:: ops:: Add < BlockCount > for BlockIdx {
77- type Output = BlockIdx ;
78- fn add ( self , rhs : BlockCount ) -> BlockIdx {
79- BlockIdx ( self . 0 + rhs. 0 )
80- }
81- }
82-
83- impl core:: ops:: AddAssign < BlockCount > for BlockIdx {
84- fn add_assign ( & mut self , rhs : BlockCount ) {
85- self . 0 += rhs. 0
86- }
87- }
88-
89- impl core:: ops:: Add < BlockCount > for BlockCount {
90- type Output = BlockCount ;
91- fn add ( self , rhs : BlockCount ) -> BlockCount {
92- BlockCount ( self . 0 + rhs. 0 )
93- }
94- }
95-
96- impl core:: ops:: AddAssign < BlockCount > for BlockCount {
97- fn add_assign ( & mut self , rhs : BlockCount ) {
98- self . 0 += rhs. 0
99- }
100- }
101-
102- impl core:: ops:: Sub < BlockCount > for BlockIdx {
103- type Output = BlockIdx ;
104- fn sub ( self , rhs : BlockCount ) -> BlockIdx {
105- BlockIdx ( self . 0 - rhs. 0 )
106- }
107- }
108-
109- impl core:: ops:: SubAssign < BlockCount > for BlockIdx {
110- fn sub_assign ( & mut self , rhs : BlockCount ) {
111- self . 0 -= rhs. 0
112- }
113- }
114-
115- impl core:: ops:: Sub < BlockCount > for BlockCount {
116- type Output = BlockCount ;
117- fn sub ( self , rhs : BlockCount ) -> BlockCount {
118- BlockCount ( self . 0 - rhs. 0 )
119- }
120- }
121-
122- impl core:: ops:: SubAssign < BlockCount > for BlockCount {
123- fn sub_assign ( & mut self , rhs : BlockCount ) {
124- self . 0 -= rhs. 0
125- }
126- }
127-
12836impl core:: ops:: Deref for Block {
12937 type Target = [ u8 ; 512 ] ;
13038 fn deref ( & self ) -> & [ u8 ; 512 ] {
@@ -159,6 +67,107 @@ impl core::fmt::Debug for Block {
15967 }
16068}
16169
70+ impl Default for Block {
71+ fn default ( ) -> Self {
72+ Self :: new ( )
73+ }
74+ }
75+
76+ /// A block device - a device which can read and write blocks (or
77+ /// sectors). Only supports devices which are <= 2 TiB in size.
78+ pub trait BlockDevice {
79+ /// The errors that the `BlockDevice` can return. Must be debug formattable.
80+ type Error : core:: fmt:: Debug ;
81+ /// Read one or more blocks, starting at the given block index.
82+ fn read ( & self , blocks : & mut [ Block ] , start_block_idx : BlockIdx ) -> Result < ( ) , Self :: Error > ;
83+ /// Write one or more blocks, starting at the given block index.
84+ fn write ( & self , blocks : & [ Block ] , start_block_idx : BlockIdx ) -> Result < ( ) , Self :: Error > ;
85+ /// Determine how many blocks this device can hold.
86+ fn num_blocks ( & self ) -> Result < BlockCount , Self :: Error > ;
87+ }
88+
89+ /// A caching layer for block devices
90+ ///
91+ /// Caches a single block.
92+ #[ derive( Debug ) ]
93+ pub struct BlockCache < D > {
94+ block_device : D ,
95+ block : [ Block ; 1 ] ,
96+ block_idx : Option < BlockIdx > ,
97+ }
98+
99+ impl < D > BlockCache < D >
100+ where
101+ D : BlockDevice ,
102+ {
103+ /// Create a new block cache
104+ pub fn new ( block_device : D ) -> BlockCache < D > {
105+ BlockCache {
106+ block_device,
107+ block : [ Block :: new ( ) ] ,
108+ block_idx : None ,
109+ }
110+ }
111+
112+ /// Read a block, and return a reference to it.
113+ pub fn read ( & mut self , block_idx : BlockIdx ) -> Result < & Block , D :: Error > {
114+ if self . block_idx != Some ( block_idx) {
115+ self . block_idx = None ;
116+ self . block_device . read ( & mut self . block , block_idx) ?;
117+ self . block_idx = Some ( block_idx) ;
118+ }
119+ Ok ( & self . block [ 0 ] )
120+ }
121+
122+ /// Read a block, and return a reference to it.
123+ pub fn read_mut ( & mut self , block_idx : BlockIdx ) -> Result < & mut Block , D :: Error > {
124+ if self . block_idx != Some ( block_idx) {
125+ self . block_idx = None ;
126+ self . block_device . read ( & mut self . block , block_idx) ?;
127+ self . block_idx = Some ( block_idx) ;
128+ }
129+ Ok ( & mut self . block [ 0 ] )
130+ }
131+
132+ /// Write back a block you read with [`Self::read_mut`] and then modified.
133+ pub fn write_back ( & mut self ) -> Result < ( ) , D :: Error > {
134+ self . block_device . write (
135+ & self . block ,
136+ self . block_idx . expect ( "write_back with no read" ) ,
137+ )
138+ }
139+
140+ /// Access a blank sector
141+ pub fn blank_mut ( & mut self , block_idx : BlockIdx ) -> & mut Block {
142+ self . block_idx = Some ( block_idx) ;
143+ for b in self . block [ 0 ] . iter_mut ( ) {
144+ * b = 0 ;
145+ }
146+ & mut self . block [ 0 ]
147+ }
148+
149+ /// Access the block device
150+ pub fn block_device ( & mut self ) -> & mut D {
151+ // invalidate the cache
152+ self . block_idx = None ;
153+ // give them the block device
154+ & mut self . block_device
155+ }
156+
157+ /// Get the block device back
158+ pub fn free ( self ) -> D {
159+ self . block_device
160+ }
161+ }
162+
163+ /// The linear numeric address of a block (or sector).
164+ ///
165+ /// The first block on a disk gets `BlockIdx(0)` (which usually contains the
166+ /// Master Boot Record).
167+ #[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
168+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
169+ pub struct BlockIdx ( pub u32 ) ;
170+
162171impl BlockIdx {
163172 /// Convert a block index into a 64-bit byte offset from the start of the
164173 /// volume. Useful if your underlying block device actually works in
@@ -174,6 +183,65 @@ impl BlockIdx {
174183 }
175184}
176185
186+ impl core:: ops:: Add < BlockCount > for BlockIdx {
187+ type Output = BlockIdx ;
188+ fn add ( self , rhs : BlockCount ) -> BlockIdx {
189+ BlockIdx ( self . 0 + rhs. 0 )
190+ }
191+ }
192+
193+ impl core:: ops:: AddAssign < BlockCount > for BlockIdx {
194+ fn add_assign ( & mut self , rhs : BlockCount ) {
195+ self . 0 += rhs. 0
196+ }
197+ }
198+
199+ impl core:: ops:: Sub < BlockCount > for BlockIdx {
200+ type Output = BlockIdx ;
201+ fn sub ( self , rhs : BlockCount ) -> BlockIdx {
202+ BlockIdx ( self . 0 - rhs. 0 )
203+ }
204+ }
205+
206+ impl core:: ops:: SubAssign < BlockCount > for BlockIdx {
207+ fn sub_assign ( & mut self , rhs : BlockCount ) {
208+ self . 0 -= rhs. 0
209+ }
210+ }
211+
212+ /// The a number of blocks (or sectors).
213+ ///
214+ /// Add this to a `BlockIdx` to get an actual address on disk.
215+ #[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
216+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
217+ pub struct BlockCount ( pub u32 ) ;
218+
219+ impl core:: ops:: Add < BlockCount > for BlockCount {
220+ type Output = BlockCount ;
221+ fn add ( self , rhs : BlockCount ) -> BlockCount {
222+ BlockCount ( self . 0 + rhs. 0 )
223+ }
224+ }
225+
226+ impl core:: ops:: AddAssign < BlockCount > for BlockCount {
227+ fn add_assign ( & mut self , rhs : BlockCount ) {
228+ self . 0 += rhs. 0
229+ }
230+ }
231+
232+ impl core:: ops:: Sub < BlockCount > for BlockCount {
233+ type Output = BlockCount ;
234+ fn sub ( self , rhs : BlockCount ) -> BlockCount {
235+ BlockCount ( self . 0 - rhs. 0 )
236+ }
237+ }
238+
239+ impl core:: ops:: SubAssign < BlockCount > for BlockCount {
240+ fn sub_assign ( & mut self , rhs : BlockCount ) {
241+ self . 0 -= rhs. 0
242+ }
243+ }
244+
177245impl BlockCount {
178246 /// How many blocks are required to hold this many bytes.
179247 ///
@@ -200,6 +268,12 @@ impl BlockCount {
200268 }
201269}
202270
271+ /// An iterator returned from `Block::range`.
272+ pub struct BlockIter {
273+ inclusive_end : BlockIdx ,
274+ current : BlockIdx ,
275+ }
276+
203277impl BlockIter {
204278 /// Create a new `BlockIter`, from the given start block, through (and
205279 /// including) the given end block.
0 commit comments