Implement read and stat for dir

This commit is contained in:
Alexander
2026-06-19 18:45:08 +02:00
parent b1f32372f7
commit 50cb21b9e5
3 changed files with 198 additions and 4 deletions
+86 -3
View File
@@ -1,9 +1,75 @@
use fuser::Filesystem;
use fuser::{
Errno, FileAttr, FileType, Filesystem, INodeNo, ReplyAttr, ReplyData, ReplyDirectory,
ReplyEntry, Request,
};
use std::env;
use std::path::Path;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, SystemTime};
struct JsonFilesystem;
impl Filesystem for JsonFilesystem {}
impl Filesystem for JsonFilesystem {
// For stat function like `stat /path/to/fuse`
fn getattr(
&self,
_req: &Request,
ino: fuser::INodeNo,
fh: Option<fuser::FileHandle>,
reply: ReplyAttr,
) {
println!("getattr(ino={})", ino);
let ts = SystemTime::now();
let attr = FileAttr {
ino: INodeNo::ROOT,
size: 0,
blocks: 0,
atime: ts,
mtime: ts,
ctime: ts,
crtime: ts,
kind: FileType::Directory,
perm: 0o755,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blksize: 0,
flags: 0,
};
let ttl = Duration::new(1, 0);
if ino == INodeNo::ROOT {
reply.attr(&ttl, &attr);
} else {
reply.error(Errno::ENOSYS);
}
}
fn readdir(
&self,
_req: &Request,
ino: INodeNo,
fh: fuser::FileHandle,
offset: u64,
mut reply: ReplyDirectory,
) {
println!("readdir(ino={}, fh={}, offset={})", ino, fh, offset);
if ino == INodeNo::ROOT {
if offset == 0 {
reply.add(INodeNo::ROOT, 0, FileType::Directory, &Path::new("."));
reply.add(INodeNo::ROOT, 1, FileType::Directory, &Path::new(".."));
}
reply.ok();
} else {
reply.error(Errno::ENOSYS);
}
}
}
fn main() {
let mountpoint = match env::args().nth(1) {
@@ -13,6 +79,23 @@ fn main() {
return;
}
};
let running = Arc::new(AtomicBool::new(true));
let r_clone = running.clone();
ctrlc::set_handler(move || {
println!("Ctrl+C received, shutting down");
r_clone.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl+C handler");
let cfg = fuser::Config::default();
let _ = fuser::mount2(JsonFilesystem, &mountpoint, &cfg);
let session = fuser::spawn_mount2(JsonFilesystem, &mountpoint, &cfg);
while running.load(Ordering::SeqCst) {
std::thread::sleep(Duration::from_millis(100));
}
println!("Unmounting");
drop(session);
}