Skip to content

Commit 09bc4ad

Browse files
fixup! Remove need for generic array and typenum constants
1 parent 199d6de commit 09bc4ad

File tree

3 files changed

+83
-45
lines changed

3 files changed

+83
-45
lines changed

core/src/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub trait Seek {
111111
fn seek(&self, pos: SeekFrom) -> Result<usize>;
112112
}
113113

114-
pub type Result<T> = core::result::Result<T, Error>;
114+
pub type Result<T, E = Error> = core::result::Result<T, E>;
115115

116116
/// The error type for filesystem operations.
117117
///

src/driver.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
//! The `Storage`, `Read`, `Write` and `Seek` driver.
22
#![allow(non_camel_case_types)]
33

4-
use crate::io::Result;
4+
use crate::io::Error;
55

66
mod private {
7+
pub struct NotEnoughCapacity;
78
pub trait Sealed {
8-
/// The maximum capacity of the buffer type.
9-
/// Can be [`usize::Max`]()
10-
const MAX_CAPACITY: usize;
11-
129
/// Returns a buffer of bytes initialized and valid. If [`set_capacity`]() was called previously,
1310
/// its last call defines the minimum number of valid bytes
1411
fn as_ptr(&self) -> *const u8;
@@ -20,8 +17,13 @@ mod private {
2017
/// or at initialization through [`with_capacity`](Buffer::with_capacity)
2118
fn current_len(&self) -> usize;
2219

23-
/// Can panic if `capacity` > `Self::MAX_CAPACITY`
24-
fn with_len(capacity: usize) -> Self;
20+
/// Atempts to set the length of the buffer to `len`
21+
///
22+
/// If succeeded, the buffer obtained through the pointer operation **must** be of at least `len` bytes
23+
fn set_len(&mut self, len: usize) -> Result<(), NotEnoughCapacity>;
24+
25+
// We could use a `Default` trait bound but it's not implemented for all array sizes
26+
fn empty() -> Self;
2527
}
2628
}
2729

@@ -31,8 +33,6 @@ pub(crate) use private::Sealed;
3133
pub unsafe trait Buffer: private::Sealed {}
3234

3335
impl<const N: usize> private::Sealed for [u8; N] {
34-
const MAX_CAPACITY: usize = N;
35-
3636
fn as_ptr(&self) -> *const u8 {
3737
<[u8]>::as_ptr(self)
3838
}
@@ -45,8 +45,15 @@ impl<const N: usize> private::Sealed for [u8; N] {
4545
N
4646
}
4747

48-
fn with_len(len: usize) -> Self {
49-
assert!(len <= N);
48+
fn set_len(&mut self, len: usize) -> Result<(), private::NotEnoughCapacity> {
49+
if len > N {
50+
Err(private::NotEnoughCapacity)
51+
} else {
52+
Ok(())
53+
}
54+
}
55+
56+
fn empty() -> Self {
5057
[0; N]
5158
}
5259
}
@@ -55,8 +62,6 @@ unsafe impl<const N: usize> Buffer for [u8; N] {}
5562

5663
#[cfg(feature = "alloc")]
5764
impl private::Sealed for alloc::vec::Vec<u8> {
58-
const MAX_CAPACITY: usize = usize::MAX;
59-
6065
fn as_ptr(&self) -> *const u8 {
6166
<[u8]>::as_ptr(self)
6267
}
@@ -69,10 +74,13 @@ impl private::Sealed for alloc::vec::Vec<u8> {
6974
self.len()
7075
}
7176

72-
fn with_len(len: usize) -> Self {
73-
let mut this = alloc::vec::Vec::with_capacity(len);
74-
this.resize(len, 0);
75-
this
77+
fn set_len(&mut self, len: usize) -> Result<(), private::NotEnoughCapacity> {
78+
self.resize(len, 0);
79+
Ok(())
80+
}
81+
82+
fn empty() -> Self {
83+
Self::new()
7684
}
7785
}
7886

@@ -156,13 +164,13 @@ pub trait Storage {
156164

157165
/// Read data from the storage device.
158166
/// Guaranteed to be called only with bufs of length a multiple of READ_SIZE.
159-
fn read(&mut self, off: usize, buf: &mut [u8]) -> Result<usize>;
167+
fn read(&mut self, off: usize, buf: &mut [u8]) -> Result<usize, Error>;
160168
/// Write data to the storage device.
161169
/// Guaranteed to be called only with bufs of length a multiple of WRITE_SIZE.
162-
fn write(&mut self, off: usize, data: &[u8]) -> Result<usize>;
170+
fn write(&mut self, off: usize, data: &[u8]) -> Result<usize, Error>;
163171
/// Erase data from the storage device.
164172
/// Guaranteed to be called only with bufs of length a multiple of BLOCK_SIZE.
165-
fn erase(&mut self, off: usize, len: usize) -> Result<usize>;
173+
fn erase(&mut self, off: usize, len: usize) -> Result<usize, Error>;
166174
// /// Synchronize writes to the storage device.
167175
// fn sync(&mut self) -> Result<usize>;
168176
}

src/fs.rs

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,15 @@ pub fn u32_result(return_value: i32) -> Result<u32> {
4242
struct Cache<Storage: driver::Storage> {
4343
read: UnsafeCell<Storage::CACHE_BUFFER>,
4444
write: UnsafeCell<Storage::CACHE_BUFFER>,
45-
// lookahead: aligned::Aligned<aligned::A4, Bytes<Storage::LOOKAHEAD_SIZE>>,
4645
lookahead: UnsafeCell<Storage::LOOKAHEAD_BUFFER>,
47-
cache_size: usize,
4846
}
4947

5048
impl<S: driver::Storage> Cache<S> {
51-
pub fn new(cache_size: usize, lookahead_size: usize) -> Self {
49+
pub fn new() -> Self {
5250
Self {
53-
read: UnsafeCell::new(S::CACHE_BUFFER::with_len(cache_size)),
54-
write: UnsafeCell::new(S::CACHE_BUFFER::with_len(cache_size)),
55-
lookahead: UnsafeCell::new(S::LOOKAHEAD_BUFFER::with_len(lookahead_size)),
56-
cache_size,
51+
read: UnsafeCell::new(S::CACHE_BUFFER::empty()),
52+
write: UnsafeCell::new(S::CACHE_BUFFER::empty()),
53+
lookahead: UnsafeCell::new(S::LOOKAHEAD_BUFFER::empty()),
5754
}
5855
}
5956
}
@@ -98,7 +95,7 @@ impl<Storage: driver::Storage> Allocation<Storage> {
9895
debug_assert!(cache_size <= block_size);
9996
debug_assert!(block_size % cache_size == 0);
10097

101-
let cache = Cache::new(cache_size as _, lookahead_size as _);
98+
let cache = Cache::new();
10299

103100
let filename_max_plus_one: u32 = crate::consts::FILENAME_MAX_PLUS_ONE;
104101
debug_assert!(filename_max_plus_one > 1);
@@ -195,7 +192,7 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
195192

196193
pub fn format(storage: &mut Storage) -> Result<()> {
197194
let alloc = &mut Allocation::new(storage);
198-
let fs = Filesystem::new(alloc, storage);
195+
let fs = Filesystem::new(alloc, storage)?;
199196
let mut alloc = fs.alloc.borrow_mut();
200197
let return_code = unsafe { ll::lfs_format(&mut alloc.state, &alloc.config) };
201198
result_from((), return_code)
@@ -527,17 +524,14 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
527524
/// The state of a `File`. Pre-allocate with `File::allocate`.
528525
pub struct FileAllocation<S: driver::Storage> {
529526
cache: UnsafeCell<S::CACHE_BUFFER>,
530-
cache_size: usize,
531527
state: ll::lfs_file_t,
532528
config: ll::lfs_file_config,
533529
}
534530

535531
impl<S: driver::Storage> FileAllocation<S> {
536-
pub fn new(cache_size: usize) -> Self {
537-
debug_assert!(cache_size > 0);
532+
pub fn new() -> Self {
538533
Self {
539-
cache: UnsafeCell::new(S::CACHE_BUFFER::with_len(cache_size)),
540-
cache_size,
534+
cache: UnsafeCell::new(S::CACHE_BUFFER::empty()),
541535
state: unsafe { mem::MaybeUninit::zeroed().assume_init() },
542536
config: unsafe { mem::MaybeUninit::zeroed().assume_init() },
543537
}
@@ -552,8 +546,8 @@ pub struct File<'a, 'b, S: driver::Storage> {
552546
}
553547

554548
impl<'a, 'b, Storage: driver::Storage> File<'a, 'b, Storage> {
555-
pub fn allocate(fs: &Filesystem<'_, Storage>) -> FileAllocation<Storage> {
556-
FileAllocation::new(fs.cache_size)
549+
pub fn allocate() -> FileAllocation<Storage> {
550+
FileAllocation::new()
557551
}
558552

559553
/// Returns a new OpenOptions object.
@@ -741,7 +735,10 @@ impl OpenOptions {
741735
alloc: &mut FileAllocation<S>,
742736
path: &Path,
743737
) -> Result<File<'a, 'b, S>> {
744-
assert_eq!(fs.cache_size, alloc.cache_size);
738+
alloc.cache.get_mut().set_len(fs.cache_size).map_err(|_| {
739+
error_now!("Buffer is not large enough for cache size of {cache_size}");
740+
Error::NO_MEMORY
741+
})?;
745742
alloc.config.buffer = alloc.cache.get_mut().as_mut_ptr() as *mut _;
746743
// We need to use addr_of_mut! here instead of & mut since
747744
// the FFI stores a copy of a pointer to the field state,
@@ -769,7 +766,7 @@ impl OpenOptions {
769766
path: &Path,
770767
f: impl FnOnce(&File<'a, '_, S>) -> Result<R>,
771768
) -> Result<R> {
772-
let mut alloc = File::allocate(fs); // lifetime 'c
769+
let mut alloc = File::allocate(); // lifetime 'c
773770
let mut file = unsafe { self.open(fs, &mut alloc, path)? };
774771
// Q: what is the actually correct behaviour?
775772
// E.g. if res is Ok but closing gives an error.
@@ -1035,7 +1032,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
10351032

10361033
impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
10371034
pub fn mount(alloc: &'a mut Allocation<Storage>, storage: &'a mut Storage) -> Result<Self> {
1038-
let fs = Self::new(alloc, storage);
1035+
let fs = Self::new(alloc, storage)?;
10391036
fs.raw_mount()?;
10401037
Ok(fs)
10411038
}
@@ -1049,7 +1046,7 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
10491046
where
10501047
F: FnOnce(Error, &mut Storage) -> Result<()>,
10511048
{
1052-
let fs = Self::new(alloc, storage);
1049+
let fs = Self::new(alloc, storage)?;
10531050
if let Err(err) = fs.raw_mount() {
10541051
f(err, fs.storage)?;
10551052
fs.raw_mount()?;
@@ -1065,18 +1062,51 @@ impl<'a, Storage: driver::Storage> Filesystem<'a, Storage> {
10651062
}
10661063

10671064
// Not public, user should use `mount`, possibly after `format`
1068-
fn new(alloc: &'a mut Allocation<Storage>, storage: &'a mut Storage) -> Self {
1065+
fn new(alloc: &'a mut Allocation<Storage>, storage: &'a mut Storage) -> Result<Self> {
1066+
let cache_size = storage.cache_size();
1067+
let lookahead_size = storage.lookahead_size();
1068+
1069+
alloc
1070+
.cache
1071+
.read
1072+
.get_mut()
1073+
.set_len(cache_size)
1074+
.map_err(|_| {
1075+
error_now!("Buffer is not large enough for cache size of {cache_size}");
1076+
Error::NO_MEMORY
1077+
})?;
1078+
alloc
1079+
.cache
1080+
.write
1081+
.get_mut()
1082+
.set_len(cache_size)
1083+
.map_err(|_| {
1084+
error_now!("Buffer is not large enough for cache size of {cache_size}");
1085+
Error::NO_MEMORY
1086+
})?;
1087+
alloc
1088+
.cache
1089+
.lookahead
1090+
.get_mut()
1091+
.set_len(lookahead_size)
1092+
.map_err(|_| {
1093+
error_now!("Buffer is not large enough for lookahead size of {lookahead_size}");
1094+
Error::NO_MEMORY
1095+
})?;
1096+
10691097
alloc.config.context = storage as *mut _ as *mut c_void;
10701098

10711099
alloc.config.read_buffer = alloc.cache.read.get_mut().as_mut_ptr() as *mut c_void;
10721100
alloc.config.prog_buffer = alloc.cache.write.get_mut().as_mut_ptr() as *mut c_void;
10731101
alloc.config.lookahead_buffer = alloc.cache.lookahead.get_mut().as_mut_ptr() as *mut c_void;
1102+
alloc.config.cache_size = cache_size as _;
1103+
alloc.config.lookahead_size = lookahead_size as _;
10741104

1075-
Filesystem {
1076-
cache_size: alloc.cache.cache_size,
1105+
Ok(Filesystem {
1106+
cache_size,
10771107
alloc: RefCell::new(alloc),
10781108
storage,
1079-
}
1109+
})
10801110
}
10811111

10821112
/// Deconstruct `Filesystem`, intention is to allow access to

0 commit comments

Comments
 (0)