Compare commits

...

2 commits

7 changed files with 703 additions and 549 deletions

55
Cargo.lock generated
View file

@ -122,6 +122,7 @@ dependencies = [
"fuser",
"libc",
"log",
"rand",
"thiserror",
]
@ -141,6 +142,18 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
@ -254,6 +267,30 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom",
]
[[package]]
name = "rustversion"
version = "1.0.21"
@ -315,6 +352,15 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
@ -454,6 +500,15 @@ dependencies = [
"windows-link",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.8.26"

View file

@ -2,7 +2,7 @@ use std::cell::RefCell;
use std::io::{Read, Seek, SeekFrom, Write};
use std::rc::Rc;
use crate::dir::{DirEntry, DirIter};
use crate::dir::DirIter;
use crate::fat::{FatError, Fatty};
use crate::subslice::{SubSlice, SubSliceMut};
@ -217,7 +217,12 @@ impl FatFs {
Ok(data)
}
pub fn root_dir_iter(&self) -> Box<dyn Iterator<Item = DirEntry> + '_> {
fn chain_reader(&self, first_cluster: u32) -> impl Read {
iter::ClusterChainReader::new(self, first_cluster)
}
pub fn root_dir_iter<'a>(&'a self) -> DirIter<Box<dyn Read + 'a>> {
// Box<dyn Iterator<Item = DirEntry> + '_>
// TODO: maybe wrap this in another RootDirIter enum, so we don't have to Box<dyn>
if let Some(root_dir_offset) = self.root_dir_offset {
@ -225,7 +230,7 @@ impl FatFs {
let sub_slice = SubSlice::new(self, root_dir_offset, self.root_dir_size);
return Box::new(DirIter::new(sub_slice));
return DirIter::new(Box::new(sub_slice));
}
// FAT32
@ -235,10 +240,15 @@ impl FatFs {
let cluster_iter = iter::ClusterChainReader::new(self, root_cluster);
Box::new(DirIter::new(cluster_iter))
DirIter::new(Box::new(cluster_iter))
}
pub fn chain_reader(&self, first_cluster: u32) -> impl Read {
iter::ClusterChainReader::new(self, first_cluster)
pub fn dir_iter<'a>(&'a self, first_cluster: u32) -> DirIter<Box<dyn Read + 'a>> {
// TODO: return type must match root_dir_iter
// if the Box<dyn> is changed there, update here as well
let cluster_iter = self.chain_reader(first_cluster);
DirIter::new(Box::new(cluster_iter))
}
}

View file

@ -68,9 +68,7 @@ fn tree(fat_fs: &FatFs, show_hidden: bool) {
}
if dir_entry.is_dir() {
let reader = fat_fs.chain_reader(dir_entry.first_cluster());
let iter = DirIter::new(reader);
let iter = fat_fs.dir_iter(dir_entry.first_cluster());
tree_impl(fat_fs, iter, show_hidden, indent + 1);
}

View file

@ -10,4 +10,5 @@ fat-bits = { version = "0.1.0", path = "../fat-bits" }
fuser = "0.15.1"
libc = "0.2.174"
log = "0.4.27"
rand = { version = "0.9.2", default-features = false, features = ["os_rng", "small_rng"] }
thiserror = "2.0.12"

572
fat-fuse/src/fuse.rs Normal file
View file

@ -0,0 +1,572 @@
use std::ffi::c_int;
use std::time::Duration;
use fuser::Filesystem;
use libc::{EIO, ENOENT, ENOSYS, ENOTDIR, EPERM};
use log::{debug, warn};
use crate::FatFuse;
impl Filesystem for FatFuse {
fn init(
&mut self,
_req: &fuser::Request<'_>,
_config: &mut fuser::KernelConfig,
) -> Result<(), c_int> {
Ok(())
}
fn destroy(&mut self) {}
fn lookup(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEntry,
) {
// warn!("[Not Implemented] lookup(parent: {:#x?}, name {:?})", parent, name);
// reply.error(ENOSYS);
let parent_inode = if let Some(inode) = self.get_inode(parent) {
inode
} else {
// parent inode does not exist
// TODO: how can we make sure this does not exist?
// panic?
reply.error(EIO);
return;
};
let Ok(dir_iter) = parent_inode.dir_iter(&self.fat_fs) else {
reply.error(ENOTDIR);
return;
};
let Some(dir_entry) =
dir_iter.find(|dir_entry| dir_entry.name_str().as_deref() == Some(""))
else {
reply.error(ENOENT);
return;
};
reply.entry(&Duration::from_secs(1), attr, generation);
todo!();
}
fn forget(&mut self, _req: &fuser::Request<'_>, _ino: u64, _nlookup: u64) {}
fn getattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: Option<u64>,
reply: fuser::ReplyAttr,
) {
warn!("[Not Implemented] getattr(ino: {:#x?}, fh: {:#x?})", ino, fh);
reply.error(ENOSYS);
}
fn setattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
mode: Option<u32>,
uid: Option<u32>,
gid: Option<u32>,
size: Option<u64>,
_atime: Option<fuser::TimeOrNow>,
_mtime: Option<fuser::TimeOrNow>,
_ctime: Option<std::time::SystemTime>,
fh: Option<u64>,
_crtime: Option<std::time::SystemTime>,
_chgtime: Option<std::time::SystemTime>,
_bkuptime: Option<std::time::SystemTime>,
flags: Option<u32>,
reply: fuser::ReplyAttr,
) {
debug!(
"[Not Implemented] setattr(ino: {:#x?}, mode: {:?}, uid: {:?}, \
gid: {:?}, size: {:?}, fh: {:?}, flags: {:?})",
ino, mode, uid, gid, size, fh, flags
);
reply.error(ENOSYS);
}
fn readlink(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyData) {
debug!("[Not Implemented] readlink(ino: {:#x?})", ino);
reply.error(ENOSYS);
}
fn mknod(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
rdev: u32,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] mknod(parent: {:#x?}, name: {:?}, mode: {}, \
umask: {:#x?}, rdev: {})",
parent, name, mode, umask, rdev
);
reply.error(ENOSYS);
}
fn mkdir(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] mkdir(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?})",
parent, name, mode, umask
);
reply.error(ENOSYS);
}
fn unlink(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] unlink(parent: {:#x?}, name: {:?})", parent, name,);
reply.error(ENOSYS);
}
fn rmdir(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] rmdir(parent: {:#x?}, name: {:?})", parent, name,);
reply.error(ENOSYS);
}
fn symlink(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
link_name: &std::ffi::OsStr,
target: &std::path::Path,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] symlink(parent: {:#x?}, link_name: {:?}, target: {:?})",
parent, link_name, target,
);
reply.error(EPERM);
}
fn rename(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
newparent: u64,
newname: &std::ffi::OsStr,
flags: u32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] rename(parent: {:#x?}, name: {:?}, newparent: {:#x?}, \
newname: {:?}, flags: {})",
parent, name, newparent, newname, flags,
);
reply.error(ENOSYS);
}
fn link(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
newparent: u64,
newname: &std::ffi::OsStr,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] link(ino: {:#x?}, newparent: {:#x?}, newname: {:?})",
ino, newparent, newname
);
reply.error(EPERM);
}
fn open(&mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen) {
reply.opened(0, 0);
}
fn read(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
size: u32,
flags: i32,
lock_owner: Option<u64>,
reply: fuser::ReplyData,
) {
warn!(
"[Not Implemented] read(ino: {:#x?}, fh: {}, offset: {}, size: {}, \
flags: {:#x?}, lock_owner: {:?})",
ino, fh, offset, size, flags, lock_owner
);
reply.error(ENOSYS);
}
fn write(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
data: &[u8],
write_flags: u32,
flags: i32,
lock_owner: Option<u64>,
reply: fuser::ReplyWrite,
) {
debug!(
"[Not Implemented] write(ino: {:#x?}, fh: {}, offset: {}, data.len(): {}, \
write_flags: {:#x?}, flags: {:#x?}, lock_owner: {:?})",
ino,
fh,
offset,
data.len(),
write_flags,
flags,
lock_owner
);
reply.error(ENOSYS);
}
fn flush(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] flush(ino: {:#x?}, fh: {}, lock_owner: {:?})",
ino, fh, lock_owner
);
reply.error(ENOSYS);
}
fn release(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_fh: u64,
_flags: i32,
_lock_owner: Option<u64>,
_flush: bool,
reply: fuser::ReplyEmpty,
) {
reply.ok();
}
fn fsync(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
datasync: bool,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] fsync(ino: {:#x?}, fh: {}, datasync: {})", ino, fh, datasync);
reply.error(ENOSYS);
}
fn opendir(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_flags: i32,
reply: fuser::ReplyOpen,
) {
reply.opened(0, 0);
}
fn readdir(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
reply: fuser::ReplyDirectory,
) {
warn!("[Not Implemented] readdir(ino: {:#x?}, fh: {}, offset: {})", ino, fh, offset);
reply.error(ENOSYS);
}
fn readdirplus(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
reply: fuser::ReplyDirectoryPlus,
) {
debug!(
"[Not Implemented] readdirplus(ino: {:#x?}, fh: {}, offset: {})",
ino, fh, offset
);
reply.error(ENOSYS);
}
fn releasedir(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_fh: u64,
_flags: i32,
reply: fuser::ReplyEmpty,
) {
reply.ok();
}
fn fsyncdir(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
datasync: bool,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] fsyncdir(ino: {:#x?}, fh: {}, datasync: {})",
ino, fh, datasync
);
reply.error(ENOSYS);
}
fn statfs(&mut self, _req: &fuser::Request<'_>, _ino: u64, reply: fuser::ReplyStatfs) {
reply.statfs(0, 0, 0, 0, 0, 512, 255, 0);
}
fn setxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
_value: &[u8],
flags: i32,
position: u32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] setxattr(ino: {:#x?}, name: {:?}, flags: {:#x?}, position: {})",
ino, name, flags, position
);
reply.error(ENOSYS);
}
fn getxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
size: u32,
reply: fuser::ReplyXattr,
) {
debug!("[Not Implemented] getxattr(ino: {:#x?}, name: {:?}, size: {})", ino, name, size);
reply.error(ENOSYS);
}
fn listxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
size: u32,
reply: fuser::ReplyXattr,
) {
debug!("[Not Implemented] listxattr(ino: {:#x?}, size: {})", ino, size);
reply.error(ENOSYS);
}
fn removexattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] removexattr(ino: {:#x?}, name: {:?})", ino, name);
reply.error(ENOSYS);
}
fn access(&mut self, _req: &fuser::Request<'_>, ino: u64, mask: i32, reply: fuser::ReplyEmpty) {
debug!("[Not Implemented] access(ino: {:#x?}, mask: {})", ino, mask);
reply.error(ENOSYS);
}
fn create(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
flags: i32,
reply: fuser::ReplyCreate,
) {
debug!(
"[Not Implemented] create(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?}, \
flags: {:#x?})",
parent, name, mode, umask, flags
);
reply.error(ENOSYS);
}
fn getlk(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
start: u64,
end: u64,
typ: i32,
pid: u32,
reply: fuser::ReplyLock,
) {
debug!(
"[Not Implemented] getlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
end: {}, typ: {}, pid: {})",
ino, fh, lock_owner, start, end, typ, pid
);
reply.error(ENOSYS);
}
fn setlk(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
start: u64,
end: u64,
typ: i32,
pid: u32,
sleep: bool,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] setlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
end: {}, typ: {}, pid: {}, sleep: {})",
ino, fh, lock_owner, start, end, typ, pid, sleep
);
reply.error(ENOSYS);
}
fn bmap(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
blocksize: u32,
idx: u64,
reply: fuser::ReplyBmap,
) {
debug!(
"[Not Implemented] bmap(ino: {:#x?}, blocksize: {}, idx: {})",
ino, blocksize, idx,
);
reply.error(ENOSYS);
}
fn ioctl(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
flags: u32,
cmd: u32,
in_data: &[u8],
out_size: u32,
reply: fuser::ReplyIoctl,
) {
debug!(
"[Not Implemented] ioctl(ino: {:#x?}, fh: {}, flags: {}, cmd: {}, \
in_data.len(): {}, out_size: {})",
ino,
fh,
flags,
cmd,
in_data.len(),
out_size,
);
reply.error(ENOSYS);
}
fn fallocate(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
length: i64,
mode: i32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] fallocate(ino: {:#x?}, fh: {}, offset: {}, \
length: {}, mode: {})",
ino, fh, offset, length, mode
);
reply.error(ENOSYS);
}
fn lseek(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
whence: i32,
reply: fuser::ReplyLseek,
) {
debug!(
"[Not Implemented] lseek(ino: {:#x?}, fh: {}, offset: {}, whence: {})",
ino, fh, offset, whence
);
reply.error(ENOSYS);
}
fn copy_file_range(
&mut self,
_req: &fuser::Request<'_>,
ino_in: u64,
fh_in: u64,
offset_in: i64,
ino_out: u64,
fh_out: u64,
offset_out: i64,
len: u64,
flags: u32,
reply: fuser::ReplyWrite,
) {
debug!(
"[Not Implemented] copy_file_range(ino_in: {:#x?}, fh_in: {}, \
offset_in: {}, ino_out: {:#x?}, fh_out: {}, offset_out: {}, \
len: {}, flags: {})",
ino_in, fh_in, offset_in, ino_out, fh_out, offset_out, len, flags
);
reply.error(ENOSYS);
}
}

View file

@ -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)))
}
}

View file

@ -1,14 +1,11 @@
mod fuse;
mod inode;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::ffi::c_int;
use std::rc::Rc;
use fat_bits::{FatFs, SliceLike};
use fuser::Filesystem;
use libc::{ENOSYS, EPERM};
use log::{debug, warn};
use crate::inode::Inode;
@ -19,6 +16,8 @@ pub struct FatFuse {
uid: u32,
gid: u32,
next_fd: u32,
inode_table: BTreeMap<u64, Inode>,
}
@ -33,544 +32,16 @@ impl FatFuse {
fat_fs,
uid,
gid,
next_fd: 0,
inode_table: BTreeMap::new(),
})
}
}
impl Filesystem for FatFuse {
fn init(
&mut self,
_req: &fuser::Request<'_>,
_config: &mut fuser::KernelConfig,
) -> Result<(), c_int> {
Ok(())
fn get_inode(&self, ino: u64) -> Option<&Inode> {
self.inode_table.get(&ino)
}
fn destroy(&mut self) {}
fn lookup(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEntry,
) {
warn!("[Not Implemented] lookup(parent: {:#x?}, name {:?})", parent, name);
reply.error(ENOSYS);
}
fn forget(&mut self, _req: &fuser::Request<'_>, _ino: u64, _nlookup: u64) {}
fn getattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: Option<u64>,
reply: fuser::ReplyAttr,
) {
warn!("[Not Implemented] getattr(ino: {:#x?}, fh: {:#x?})", ino, fh);
reply.error(ENOSYS);
}
fn setattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
mode: Option<u32>,
uid: Option<u32>,
gid: Option<u32>,
size: Option<u64>,
_atime: Option<fuser::TimeOrNow>,
_mtime: Option<fuser::TimeOrNow>,
_ctime: Option<std::time::SystemTime>,
fh: Option<u64>,
_crtime: Option<std::time::SystemTime>,
_chgtime: Option<std::time::SystemTime>,
_bkuptime: Option<std::time::SystemTime>,
flags: Option<u32>,
reply: fuser::ReplyAttr,
) {
debug!(
"[Not Implemented] setattr(ino: {:#x?}, mode: {:?}, uid: {:?}, \
gid: {:?}, size: {:?}, fh: {:?}, flags: {:?})",
ino, mode, uid, gid, size, fh, flags
);
reply.error(ENOSYS);
}
fn readlink(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyData) {
debug!("[Not Implemented] readlink(ino: {:#x?})", ino);
reply.error(ENOSYS);
}
fn mknod(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
rdev: u32,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] mknod(parent: {:#x?}, name: {:?}, mode: {}, \
umask: {:#x?}, rdev: {})",
parent, name, mode, umask, rdev
);
reply.error(ENOSYS);
}
fn mkdir(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] mkdir(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?})",
parent, name, mode, umask
);
reply.error(ENOSYS);
}
fn unlink(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] unlink(parent: {:#x?}, name: {:?})", parent, name,);
reply.error(ENOSYS);
}
fn rmdir(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] rmdir(parent: {:#x?}, name: {:?})", parent, name,);
reply.error(ENOSYS);
}
fn symlink(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
link_name: &std::ffi::OsStr,
target: &std::path::Path,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] symlink(parent: {:#x?}, link_name: {:?}, target: {:?})",
parent, link_name, target,
);
reply.error(EPERM);
}
fn rename(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
newparent: u64,
newname: &std::ffi::OsStr,
flags: u32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] rename(parent: {:#x?}, name: {:?}, newparent: {:#x?}, \
newname: {:?}, flags: {})",
parent, name, newparent, newname, flags,
);
reply.error(ENOSYS);
}
fn link(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
newparent: u64,
newname: &std::ffi::OsStr,
reply: fuser::ReplyEntry,
) {
debug!(
"[Not Implemented] link(ino: {:#x?}, newparent: {:#x?}, newname: {:?})",
ino, newparent, newname
);
reply.error(EPERM);
}
fn open(&mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen) {
reply.opened(0, 0);
}
fn read(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
size: u32,
flags: i32,
lock_owner: Option<u64>,
reply: fuser::ReplyData,
) {
warn!(
"[Not Implemented] read(ino: {:#x?}, fh: {}, offset: {}, size: {}, \
flags: {:#x?}, lock_owner: {:?})",
ino, fh, offset, size, flags, lock_owner
);
reply.error(ENOSYS);
}
fn write(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
data: &[u8],
write_flags: u32,
flags: i32,
lock_owner: Option<u64>,
reply: fuser::ReplyWrite,
) {
debug!(
"[Not Implemented] write(ino: {:#x?}, fh: {}, offset: {}, data.len(): {}, \
write_flags: {:#x?}, flags: {:#x?}, lock_owner: {:?})",
ino,
fh,
offset,
data.len(),
write_flags,
flags,
lock_owner
);
reply.error(ENOSYS);
}
fn flush(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] flush(ino: {:#x?}, fh: {}, lock_owner: {:?})",
ino, fh, lock_owner
);
reply.error(ENOSYS);
}
fn release(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_fh: u64,
_flags: i32,
_lock_owner: Option<u64>,
_flush: bool,
reply: fuser::ReplyEmpty,
) {
reply.ok();
}
fn fsync(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
datasync: bool,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] fsync(ino: {:#x?}, fh: {}, datasync: {})", ino, fh, datasync);
reply.error(ENOSYS);
}
fn opendir(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_flags: i32,
reply: fuser::ReplyOpen,
) {
reply.opened(0, 0);
}
fn readdir(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
reply: fuser::ReplyDirectory,
) {
warn!("[Not Implemented] readdir(ino: {:#x?}, fh: {}, offset: {})", ino, fh, offset);
reply.error(ENOSYS);
}
fn readdirplus(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
reply: fuser::ReplyDirectoryPlus,
) {
debug!(
"[Not Implemented] readdirplus(ino: {:#x?}, fh: {}, offset: {})",
ino, fh, offset
);
reply.error(ENOSYS);
}
fn releasedir(
&mut self,
_req: &fuser::Request<'_>,
_ino: u64,
_fh: u64,
_flags: i32,
reply: fuser::ReplyEmpty,
) {
reply.ok();
}
fn fsyncdir(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
datasync: bool,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] fsyncdir(ino: {:#x?}, fh: {}, datasync: {})",
ino, fh, datasync
);
reply.error(ENOSYS);
}
fn statfs(&mut self, _req: &fuser::Request<'_>, _ino: u64, reply: fuser::ReplyStatfs) {
reply.statfs(0, 0, 0, 0, 0, 512, 255, 0);
}
fn setxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
_value: &[u8],
flags: i32,
position: u32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] setxattr(ino: {:#x?}, name: {:?}, flags: {:#x?}, position: {})",
ino, name, flags, position
);
reply.error(ENOSYS);
}
fn getxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
size: u32,
reply: fuser::ReplyXattr,
) {
debug!("[Not Implemented] getxattr(ino: {:#x?}, name: {:?}, size: {})", ino, name, size);
reply.error(ENOSYS);
}
fn listxattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
size: u32,
reply: fuser::ReplyXattr,
) {
debug!("[Not Implemented] listxattr(ino: {:#x?}, size: {})", ino, size);
reply.error(ENOSYS);
}
fn removexattr(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
name: &std::ffi::OsStr,
reply: fuser::ReplyEmpty,
) {
debug!("[Not Implemented] removexattr(ino: {:#x?}, name: {:?})", ino, name);
reply.error(ENOSYS);
}
fn access(&mut self, _req: &fuser::Request<'_>, ino: u64, mask: i32, reply: fuser::ReplyEmpty) {
debug!("[Not Implemented] access(ino: {:#x?}, mask: {})", ino, mask);
reply.error(ENOSYS);
}
fn create(
&mut self,
_req: &fuser::Request<'_>,
parent: u64,
name: &std::ffi::OsStr,
mode: u32,
umask: u32,
flags: i32,
reply: fuser::ReplyCreate,
) {
debug!(
"[Not Implemented] create(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?}, \
flags: {:#x?})",
parent, name, mode, umask, flags
);
reply.error(ENOSYS);
}
fn getlk(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
start: u64,
end: u64,
typ: i32,
pid: u32,
reply: fuser::ReplyLock,
) {
debug!(
"[Not Implemented] getlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
end: {}, typ: {}, pid: {})",
ino, fh, lock_owner, start, end, typ, pid
);
reply.error(ENOSYS);
}
fn setlk(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
lock_owner: u64,
start: u64,
end: u64,
typ: i32,
pid: u32,
sleep: bool,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] setlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
end: {}, typ: {}, pid: {}, sleep: {})",
ino, fh, lock_owner, start, end, typ, pid, sleep
);
reply.error(ENOSYS);
}
fn bmap(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
blocksize: u32,
idx: u64,
reply: fuser::ReplyBmap,
) {
debug!(
"[Not Implemented] bmap(ino: {:#x?}, blocksize: {}, idx: {})",
ino, blocksize, idx,
);
reply.error(ENOSYS);
}
fn ioctl(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
flags: u32,
cmd: u32,
in_data: &[u8],
out_size: u32,
reply: fuser::ReplyIoctl,
) {
debug!(
"[Not Implemented] ioctl(ino: {:#x?}, fh: {}, flags: {}, cmd: {}, \
in_data.len(): {}, out_size: {})",
ino,
fh,
flags,
cmd,
in_data.len(),
out_size,
);
reply.error(ENOSYS);
}
fn fallocate(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
length: i64,
mode: i32,
reply: fuser::ReplyEmpty,
) {
debug!(
"[Not Implemented] fallocate(ino: {:#x?}, fh: {}, offset: {}, \
length: {}, mode: {})",
ino, fh, offset, length, mode
);
reply.error(ENOSYS);
}
fn lseek(
&mut self,
_req: &fuser::Request<'_>,
ino: u64,
fh: u64,
offset: i64,
whence: i32,
reply: fuser::ReplyLseek,
) {
debug!(
"[Not Implemented] lseek(ino: {:#x?}, fh: {}, offset: {}, whence: {})",
ino, fh, offset, whence
);
reply.error(ENOSYS);
}
fn copy_file_range(
&mut self,
_req: &fuser::Request<'_>,
ino_in: u64,
fh_in: u64,
offset_in: i64,
ino_out: u64,
fh_out: u64,
offset_out: i64,
len: u64,
flags: u32,
reply: fuser::ReplyWrite,
) {
debug!(
"[Not Implemented] copy_file_range(ino_in: {:#x?}, fh_in: {}, \
offset_in: {}, ino_out: {:#x?}, fh_out: {}, offset_out: {}, \
len: {}, flags: {})",
ino_in, fh_in, offset_in, ino_out, fh_out, offset_out, len, flags
);
reply.error(ENOSYS);
fn get_inode_mut(&mut self, ino: u64) -> Option<&mut Inode> {
self.inode_table.get_mut(&ino)
}
}