33//! Generic code for handling block devices, such as types for identifying
44//! a particular block on a block device by its index.
55
6+ use embedded_storage:: BlockDevice ;
7+
68/// A standard 512 byte block (also known as a sector).
79///
810/// IBM PC formatted 5.25" and 3.5" floppy disks, IDE/SATA Hard Drives up to
911/// about 2 TiB, and almost all SD/MMC cards have 512 byte blocks.
1012///
1113/// This library does not support devices with a block size other than 512
1214/// bytes.
13- #[ derive( Clone ) ]
14- pub struct Block {
15- /// The 512 bytes in this block (or sector).
16- pub contents : [ u8 ; Block :: LEN ] ,
17- }
15+ pub type Block = [ u8 ; BLOCK_LEN ] ;
1816
19- impl Block {
20- /// All our blocks are a fixed length of 512 bytes. We do not support
21- /// 'Advanced Format' Hard Drives with 4 KiB blocks, nor weird old
22- /// pre-3.5-inch floppy disk formats.
23- pub const LEN : usize = 512 ;
17+ /// All our blocks are a fixed length of 512 bytes. We do not support
18+ /// 'Advanced Format' Hard Drives with 4 KiB blocks, nor weird old
19+ /// pre-3.5-inch floppy disk formats.
20+ pub const BLOCK_LEN : usize = 512 ;
2421
25- /// Sometimes we want `LEN` as a `u32` and the casts don't look nice.
26- pub const LEN_U32 : u32 = 512 ;
22+ /// Sometimes we want `LEN` as a `u32` and the casts don't look nice.
23+ pub const BLOCK_LEN_U32 : u32 = 512 ;
2724
28- /// Create a new block full of zeros.
29- pub fn new ( ) -> Block {
30- Block {
31- contents : [ 0u8 ; Self :: LEN ] ,
32- }
33- }
34- }
35-
36- impl core:: ops:: Deref for Block {
37- type Target = [ u8 ; 512 ] ;
38- fn deref ( & self ) -> & [ u8 ; 512 ] {
39- & self . contents
40- }
41- }
42-
43- impl core:: ops:: DerefMut for Block {
44- fn deref_mut ( & mut self ) -> & mut [ u8 ; 512 ] {
45- & mut self . contents
46- }
47- }
48-
49- impl core:: fmt:: Debug for Block {
50- fn fmt ( & self , fmt : & mut core:: fmt:: Formatter ) -> core:: fmt:: Result {
51- writeln ! ( fmt, "Block:" ) ?;
52- for line in self . contents . chunks ( 32 ) {
53- for b in line {
54- write ! ( fmt, "{:02x}" , b) ?;
55- }
56- write ! ( fmt, " " ) ?;
57- for & b in line {
58- if ( 0x20 ..=0x7F ) . contains ( & b) {
59- write ! ( fmt, "{}" , b as char ) ?;
60- } else {
61- write ! ( fmt, "." ) ?;
62- }
63- }
64- writeln ! ( fmt) ?;
65- }
66- Ok ( ( ) )
67- }
68- }
69-
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- }
25+ /// Sometimes we want `LEN` as a `u64` and the casts don't look nice.
26+ pub const BLOCK_LEN_U64 : u64 = 512 ;
8827
8928/// A caching layer for block devices
9029///
@@ -93,7 +32,7 @@ pub trait BlockDevice {
9332pub struct BlockCache < D > {
9433 block_device : D ,
9534 block : [ Block ; 1 ] ,
96- block_idx : Option < BlockIdx > ,
35+ block_idx : Option < u64 > ,
9736}
9837
9938impl < D > BlockCache < D >
@@ -104,26 +43,26 @@ where
10443 pub fn new ( block_device : D ) -> BlockCache < D > {
10544 BlockCache {
10645 block_device,
107- block : [ Block :: new ( ) ] ,
46+ block : [ [ 0 ; BLOCK_LEN ] ] ,
10847 block_idx : None ,
10948 }
11049 }
11150
11251 /// Read a block, and return a reference to it.
113- pub fn read ( & mut self , block_idx : BlockIdx ) -> Result < & Block , D :: Error > {
52+ pub fn read ( & mut self , block_idx : u64 ) -> Result < & Block , D :: Error > {
11453 if self . block_idx != Some ( block_idx) {
11554 self . block_idx = None ;
116- self . block_device . read ( & mut self . block , block_idx ) ?;
55+ self . block_device . read ( block_idx , & mut self . block ) ?;
11756 self . block_idx = Some ( block_idx) ;
11857 }
11958 Ok ( & self . block [ 0 ] )
12059 }
12160
12261 /// Read a block, and return a reference to it.
123- pub fn read_mut ( & mut self , block_idx : BlockIdx ) -> Result < & mut Block , D :: Error > {
62+ pub fn read_mut ( & mut self , block_idx : u64 ) -> Result < & mut Block , D :: Error > {
12463 if self . block_idx != Some ( block_idx) {
12564 self . block_idx = None ;
126- self . block_device . read ( & mut self . block , block_idx ) ?;
65+ self . block_device . read ( block_idx , & mut self . block ) ?;
12766 self . block_idx = Some ( block_idx) ;
12867 }
12968 Ok ( & mut self . block [ 0 ] )
@@ -132,13 +71,13 @@ where
13271 /// Write back a block you read with [`Self::read_mut`] and then modified.
13372 pub fn write_back ( & mut self ) -> Result < ( ) , D :: Error > {
13473 self . block_device . write (
135- & self . block ,
13674 self . block_idx . expect ( "write_back with no read" ) ,
75+ & self . block ,
13776 )
13877 }
13978
14079 /// Access a blank sector
141- pub fn blank_mut ( & mut self , block_idx : BlockIdx ) -> & mut Block {
80+ pub fn blank_mut ( & mut self , block_idx : u64 ) -> & mut Block {
14281 self . block_idx = Some ( block_idx) ;
14382 for b in self . block [ 0 ] . iter_mut ( ) {
14483 * b = 0 ;
@@ -173,7 +112,7 @@ impl BlockIdx {
173112 /// volume. Useful if your underlying block device actually works in
174113 /// bytes, like `open("/dev/mmcblk0")` does on Linux.
175114 pub fn into_bytes ( self ) -> u64 {
176- ( u64:: from ( self . 0 ) ) * ( Block :: LEN as u64 )
115+ u64:: from ( self . 0 ) * BLOCK_LEN_U64
177116 }
178117
179118 /// Create an iterator from the current `BlockIdx` through the given
@@ -183,6 +122,12 @@ impl BlockIdx {
183122 }
184123}
185124
125+ impl From < BlockIdx > for u64 {
126+ fn from ( value : BlockIdx ) -> Self {
127+ value. 0 . into ( )
128+ }
129+ }
130+
186131impl core:: ops:: Add < BlockCount > for BlockIdx {
187132 type Output = BlockIdx ;
188133 fn add ( self , rhs : BlockCount ) -> BlockIdx {
@@ -254,8 +199,8 @@ impl BlockCount {
254199 /// assert_eq!(BlockCount::from_bytes(1025), BlockCount(3));
255200 /// ```
256201 pub const fn from_bytes ( byte_count : u32 ) -> BlockCount {
257- let mut count = byte_count / Block :: LEN_U32 ;
258- if ( count * Block :: LEN_U32 ) != byte_count {
202+ let mut count = byte_count / BLOCK_LEN_U32 ;
203+ if ( count * BLOCK_LEN_U32 ) != byte_count {
259204 count += 1 ;
260205 }
261206 BlockCount ( count)
@@ -264,7 +209,7 @@ impl BlockCount {
264209 /// Take a number of blocks and increment by the integer number of blocks
265210 /// required to get to the block that holds the byte at the given offset.
266211 pub fn offset_bytes ( self , offset : u32 ) -> Self {
267- BlockCount ( self . 0 + ( offset / Block :: LEN_U32 ) )
212+ BlockCount ( self . 0 + ( offset / BLOCK_LEN_U32 ) )
268213 }
269214}
270215
0 commit comments