refactor(fs/fat32): move bpb to data.rs

This commit is contained in:
2021-10-29 12:10:08 +03:00
parent 9f62396ebc
commit df14db3833
3 changed files with 43 additions and 106 deletions
+30
View File
@@ -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
}
}
+1 -1
View File
@@ -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)
}?;
+12 -105
View File
@@ -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<Bpb>,
@@ -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<Self>) -> Result<VnodeRef, Errno> {
self.root.borrow().clone().ok_or(Errno::DoesNotExist)
@@ -55,17 +41,6 @@ impl Filesystem for Fat32 {
}
impl Fat32 {
fn create_node(self: Rc<Self>, 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<Rc<Self>, 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<Option<File>>,
}
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");
}
}