Separate options type for FileStorage, remove hardcoded constants

This commit is contained in:
Egor Duda
2022-06-05 22:40:59 +03:00
parent c0299c3225
commit 4e47968233

View File

@@ -17,7 +17,7 @@
//! [`FileStorage`] implements the flash [`Storage`] interface but doesn't interface with an //! [`FileStorage`] implements the flash [`Storage`] interface but doesn't interface with an
//! actual flash storage. Instead it uses a host-based file to persist the storage state. //! actual flash storage. Instead it uses a host-based file to persist the storage state.
use crate::{BufferOptions, Storage, StorageIndex, StorageResult}; use crate::{Storage, StorageIndex, StorageResult};
use alloc::borrow::Cow; use alloc::borrow::Cow;
use core::cell::RefCell; use core::cell::RefCell;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
@@ -29,7 +29,7 @@ use std::path::Path;
/// This is usable for emulating authenticator hardware on VM hypervisor's host OS /// This is usable for emulating authenticator hardware on VM hypervisor's host OS
pub struct FileStorage { pub struct FileStorage {
// Options of the storage // Options of the storage
buffer_options: BufferOptions, options: FileOptions,
/// File for persisting contents of the storage /// File for persisting contents of the storage
/// Reading data from File requires mutable reference, as seeking and reading data /// Reading data from File requires mutable reference, as seeking and reading data
@@ -39,19 +39,20 @@ pub struct FileStorage {
backing_file_ref: RefCell<File>, backing_file_ref: RefCell<File>,
} }
const PAGE_SIZE: usize = 0x1000; /// Options for file-backed storage
const NUM_PAGES: usize = 20; pub struct FileOptions {
/// Size of a word in bytes.
pub word_size: usize,
/// Size of a page in bytes.
pub page_size: usize,
/// Number of pages in storage
pub num_pages: usize,
}
impl FileStorage { impl FileStorage {
pub fn new(path: &Path) -> StorageResult<FileStorage> { pub fn new(path: &Path, options: FileOptions) -> StorageResult<FileStorage> {
let buffer_options = BufferOptions {
word_size: 4,
page_size: PAGE_SIZE,
max_word_writes: 2,
max_page_erases: 10000,
strict_mode: true,
};
let mut backing_file_ref = RefCell::new( let mut backing_file_ref = RefCell::new(
OpenOptions::new() OpenOptions::new()
.read(true) .read(true)
@@ -61,12 +62,12 @@ impl FileStorage {
); );
let backing_file = backing_file_ref.get_mut(); let backing_file = backing_file_ref.get_mut();
let file_len = backing_file.metadata()?.len(); let file_len = backing_file.metadata()?.len();
let store_len: u64 = (PAGE_SIZE * NUM_PAGES) as u64; let store_len: u64 = (options.page_size * options.num_pages) as u64;
if file_len == 0 { if file_len == 0 {
backing_file.seek(SeekFrom::Start(0))?; backing_file.seek(SeekFrom::Start(0))?;
for _ in 0..NUM_PAGES { let buf = vec![0xffu8; options.page_size];
let buf = [0xffu8; PAGE_SIZE]; for _ in 0..options.num_pages {
backing_file.write(&buf)?; backing_file.write(&buf)?;
} }
} else if file_len != store_len { } else if file_len != store_len {
@@ -75,7 +76,7 @@ impl FileStorage {
panic!("Invalid file size {}, should be {}", file_len, store_len); panic!("Invalid file size {}, should be {}", file_len, store_len);
} }
Ok(FileStorage { Ok(FileStorage {
buffer_options, options,
backing_file_ref, backing_file_ref,
}) })
} }
@@ -83,23 +84,23 @@ impl FileStorage {
impl Storage for FileStorage { impl Storage for FileStorage {
fn word_size(&self) -> usize { fn word_size(&self) -> usize {
self.buffer_options.word_size self.options.word_size
} }
fn page_size(&self) -> usize { fn page_size(&self) -> usize {
self.buffer_options.page_size self.options.page_size
} }
fn num_pages(&self) -> usize { fn num_pages(&self) -> usize {
NUM_PAGES self.options.num_pages
} }
fn max_word_writes(&self) -> usize { fn max_word_writes(&self) -> usize {
self.buffer_options.max_word_writes usize::MAX
} }
fn max_page_erases(&self) -> usize { fn max_page_erases(&self) -> usize {
self.buffer_options.max_page_erases usize::MAX
} }
fn read_slice(&self, index: StorageIndex, length: usize) -> StorageResult<Cow<[u8]>> { fn read_slice(&self, index: StorageIndex, length: usize) -> StorageResult<Cow<[u8]>> {
@@ -140,6 +141,12 @@ mod tests {
const FILE_NAME: &str = "opensk_storage.bin"; const FILE_NAME: &str = "opensk_storage.bin";
const OPTIONS: FileOptions = FileOptions {
word_size: 4,
page_size: 0x1000,
num_pages: 20,
};
fn make_tmp_dir() -> PathBuf { fn make_tmp_dir() -> PathBuf {
let tmp_dir = TempDir::new().unwrap(); let tmp_dir = TempDir::new().unwrap();
tmp_dir.into_path() tmp_dir.into_path()
@@ -152,7 +159,7 @@ mod tests {
fn temp_storage(tmp_dir: &PathBuf) -> FileStorage { fn temp_storage(tmp_dir: &PathBuf) -> FileStorage {
let mut tmp_file = tmp_dir.clone(); let mut tmp_file = tmp_dir.clone();
tmp_file.push(FILE_NAME); tmp_file.push(FILE_NAME);
FileStorage::new(&tmp_file).unwrap() FileStorage::new(&tmp_file, OPTIONS).unwrap()
} }
#[test] #[test]