moved FUSE impl into separate file, more work on inodes
This commit is contained in:
parent
3c977d2d42
commit
372aa34022
5 changed files with 686 additions and 540 deletions
|
|
@ -1,11 +1,35 @@
|
|||
use std::cell::{LazyCell, RefCell};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use chrono::{NaiveDateTime, NaiveTime};
|
||||
use fat_bits::FatFs;
|
||||
use fat_bits::dir::DirEntry;
|
||||
use fat_bits::dir::{DirEntry, DirIter};
|
||||
use fuser::FileAttr;
|
||||
use rand::{Rng, SeedableRng as _};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
thread_local! {
|
||||
/// SAFETY
|
||||
///
|
||||
/// do not access this directly, only invoke the get_random_u32 function
|
||||
// static RNG: LazyCell<UnsafeCell<rand::rngs::SmallRng>> = LazyCell::new(|| UnsafeCell::new(rand::rngs::SmallRng::from_os_rng()));
|
||||
|
||||
/// performance should not be a bottleneck here, since we only need to occasionally generate u32s to
|
||||
/// be used as generations in inodes
|
||||
/// if at some point (contrary to expectations) it should become, can switch it to an UnsafeCell
|
||||
static RNG: LazyCell<RefCell<rand::rngs::SmallRng>> = LazyCell::new(|| RefCell::new(rand::rngs::SmallRng::from_os_rng()));
|
||||
}
|
||||
|
||||
fn get_random_u32() -> u32 {
|
||||
// RNG.with(|x| unsafe {
|
||||
// let rng = &mut (*x.get());
|
||||
|
||||
// rng.random::<u32>()
|
||||
// })
|
||||
|
||||
RNG.with(|rng| rng.borrow_mut().random())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Kind {
|
||||
File,
|
||||
Dir,
|
||||
|
|
@ -20,13 +44,15 @@ impl From<Kind> for fuser::FileType {
|
|||
}
|
||||
}
|
||||
|
||||
const ROOT_INO: u64 = 1;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Inode {
|
||||
ino: u64,
|
||||
generation: u32,
|
||||
|
||||
size: u64,
|
||||
// blocks: u64,
|
||||
block_size: u32,
|
||||
|
||||
kind: Kind,
|
||||
|
|
@ -49,6 +75,8 @@ impl Inode {
|
|||
pub fn new(fat_fs: &FatFs, dir_entry: DirEntry, uid: u32, gid: u32) -> Inode {
|
||||
assert!(dir_entry.is_file() || dir_entry.is_dir());
|
||||
|
||||
let generation = get_random_u32();
|
||||
|
||||
let kind = if dir_entry.is_dir() {
|
||||
Kind::Dir
|
||||
} else {
|
||||
|
|
@ -69,6 +97,7 @@ impl Inode {
|
|||
|
||||
Inode {
|
||||
ino: dir_entry.first_cluster() as u64,
|
||||
generation,
|
||||
size: dir_entry.file_size() as u64,
|
||||
block_size: fat_fs.bpb().bytes_per_sector() as u32,
|
||||
kind,
|
||||
|
|
@ -103,4 +132,22 @@ impl Inode {
|
|||
flags: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dir_iter(&self, fat_fs: &FatFs) -> anyhow::Result<impl Iterator<Item = DirEntry>> {
|
||||
anyhow::ensure!(self.kind == Kind::Dir, "cannot dir_iter on a file");
|
||||
|
||||
// TODO: the boxing here is not particularly pretty, but neccessary, since the DirIter for
|
||||
// the root holds a
|
||||
|
||||
if self.ino == ROOT_INO {
|
||||
// root dir
|
||||
|
||||
return Ok(fat_fs.root_dir_iter());
|
||||
}
|
||||
|
||||
let chain_reader = fat_fs.chain_reader(self.first_cluster);
|
||||
|
||||
// TODO: get rid of this Box if the boxing is removed from root_dir_iter
|
||||
Ok(DirIter::new(Box::new(chain_reader)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue