From df14db383377a84446978177a5da4af01a2a92e4 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Fri, 29 Oct 2021 12:10:08 +0300 Subject: [PATCH] refactor(fs/fat32): move bpb to data.rs --- fs/fat32/src/data.rs | 30 +++++++++++ fs/fat32/src/dir.rs | 2 +- fs/fat32/src/lib.rs | 117 +++++-------------------------------------- 3 files changed, 43 insertions(+), 106 deletions(-) create mode 100644 fs/fat32/src/data.rs diff --git a/fs/fat32/src/data.rs b/fs/fat32/src/data.rs new file mode 100644 index 0000000..469ac83 --- /dev/null +++ b/fs/fat32/src/data.rs @@ -0,0 +1,30 @@ +use libcommon::{read_le16, read_le32}; + +#[derive(Debug)] +pub struct Bpb { + sectors_per_cluster: u8, + reserved_sectors: u16, + fat_count: u8, + sectors_per_fat: u32, +} + +impl Bpb { + pub fn from_sector(data: &[u8]) -> Self { + Self { + fat_count: data[16], + reserved_sectors: read_le16(&data[14..]), + sectors_per_cluster: data[13], + sectors_per_fat: read_le32(&data[36..]), + } + } + + pub const fn cluster_base_sector(&self, cluster: u32) -> u32 { + let first_data_sector = + self.reserved_sectors as u32 + (self.fat_count as u32 * self.sectors_per_fat as u32); + ((cluster - 2) * self.sectors_per_cluster as u32) + first_data_sector + } + + pub const fn sectors_per_cluster(&self) -> u8 { + self.sectors_per_cluster + } +} diff --git a/fs/fat32/src/dir.rs b/fs/fat32/src/dir.rs index de63679..d00ecee 100644 --- a/fs/fat32/src/dir.rs +++ b/fs/fat32/src/dir.rs @@ -49,7 +49,7 @@ impl VnodeImpl for DirectoryInode { let bpb: &Bpb = fs_data.as_ref().and_then(|e| e.downcast_ref()).unwrap(); let sector = bpb.cluster_base_sector(self.cluster); - FatIterator::new(dev, sector, bpb.sectors_per_cluster) + FatIterator::new(dev, sector, bpb.sectors_per_cluster()) .find(|ent| ent.name == name) .ok_or(Errno::DoesNotExist) }?; diff --git a/fs/fat32/src/lib.rs b/fs/fat32/src/lib.rs index a2367b8..27e31ce 100644 --- a/fs/fat32/src/lib.rs +++ b/fs/fat32/src/lib.rs @@ -6,25 +6,19 @@ extern crate std; extern crate alloc; -use alloc::{rc::Rc, boxed::Box}; +use alloc::{boxed::Box, rc::Rc}; use core::any::Any; use core::cell::{Ref, RefCell}; use error::Errno; -use libcommon::{read_le16, read_le32}; +use libcommon::read_le32; use vfs::{BlockDevice, Filesystem, Vnode, VnodeKind, VnodeRef}; pub mod dir; -pub use dir::{Dirent as FatEntry, FatIterator, DirectoryInode}; +pub use dir::{DirectoryInode, Dirent as FatEntry, FatIterator}; pub mod file; pub use file::FileInode; - -#[derive(Debug)] -struct Bpb { - sectors_per_cluster: u8, - reserved_sectors: u16, - fat_count: u8, - sectors_per_fat: u32, -} +pub mod data; +pub use data::Bpb; pub struct Fat32 { bpb: RefCell, @@ -32,14 +26,6 @@ pub struct Fat32 { dev: &'static dyn BlockDevice, } -impl Bpb { - pub const fn cluster_base_sector(&self, cluster: u32) -> u32 { - let first_data_sector = self.reserved_sectors as u32 - + (self.fat_count as u32 * self.sectors_per_fat as u32); - ((cluster - 2) * self.sectors_per_cluster as u32) + first_data_sector - } -} - impl Filesystem for Fat32 { fn root(self: Rc) -> Result { self.root.borrow().clone().ok_or(Errno::DoesNotExist) @@ -55,17 +41,6 @@ impl Filesystem for Fat32 { } impl Fat32 { - fn create_node(self: Rc, name: &str, kind: VnodeKind, cluster: u32) -> VnodeRef { - let res = Vnode::new(name, kind, Vnode::SEEKABLE); - - res.set_fs(self.clone()); - res.set_data(match kind { - VnodeKind::Directory => Box::new(DirectoryInode { cluster }), - _ => todo!(), - }); - res - } - pub fn open(dev: &'static dyn BlockDevice) -> Result, Errno> { let mut buf = [0u8; 512]; @@ -78,86 +53,18 @@ impl Fat32 { let root_cluster = read_le32(&buf[44..]); let res = Rc::new(Self { - bpb: RefCell::new(Bpb { - fat_count: buf[16], - reserved_sectors: read_le16(&buf[14..]), - sectors_per_cluster: buf[13], - sectors_per_fat: read_le32(&buf[36..]), - }), + bpb: RefCell::new(Bpb::from_sector(&buf)), dev, root: RefCell::new(None), }); - *res.root.borrow_mut() = Some(res.clone().create_node( - "", - VnodeKind::Directory, - root_cluster, - )); + let root = Vnode::new("", VnodeKind::Directory, Vnode::SEEKABLE); + root.set_fs(res.clone()); + root.set_data(Box::new(DirectoryInode { + cluster: root_cluster, + })); + *res.root.borrow_mut() = Some(root); Ok(res) } } - -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - use std::fs::File; - use std::io::{Read, Seek, SeekFrom}; - use libcommon::{Read as LRead}; - use vfs::Ioctx; - - struct FileBlockDevice { - file: RefCell>, - } - - impl FileBlockDevice { - pub const fn new() -> Self { - Self { - file: RefCell::new(None), - } - } - - pub fn open(&self, path: &str) { - *self.file.borrow_mut() = Some(File::open(path).unwrap()); - } - } - - impl BlockDevice for FileBlockDevice { - fn read(&self, pos: usize, buf: &mut [u8]) -> Result<(), Errno> { - let mut borrow = self.file.borrow_mut(); - let file = borrow.as_mut().unwrap(); - file.seek(SeekFrom::Start(pos as u64)).unwrap(); - if file.read(buf).unwrap() != buf.len() { - Err(Errno::InvalidArgument) - } else { - Ok(()) - } - } - - fn write(&self, _pos: usize, _buf: &[u8]) -> Result<(), Errno> { - todo!() - } - } - - unsafe impl Sync for FileBlockDevice {} - - #[test] - fn test_fat32_open() { - static DEV: FileBlockDevice = FileBlockDevice::new(); - - DEV.open("test/test0.img"); - - let fs = Fat32::open(&DEV).unwrap(); - let root = fs.root().unwrap(); - let ioctx = Ioctx::new(root); - - let mut buf = [0u8; 512]; - let node0 = ioctx.find(None, "FILENAME.TXT").unwrap(); - let mut file = node0.open().unwrap(); - - let count = file.read(&mut buf).unwrap(); - assert_eq!(count, 15); - assert_eq!(&buf[..15], b"This is a file\n"); - } -}