Interestingly rust seems to make a distinction between files and directories. In C both are queried by getattr while in rust getattr is for directories and lookup is for files. Very curious.
use std::time::{Duration, UNIX_EPOCH};
use std::ffi::OsStr;
use fuser::{
FileAttr, FileType, Filesystem, ReplyAttr, ReplyDirectory, ReplyEntry, Request,
};
struct RFS;
const ENOENT :i32 = 2;
const TTL: Duration = Duration::from_secs(1);
const DEFAULT_DIR_ATTR: FileAttr = FileAttr {
ino: 1,
size: 4096,
blocks: 0,
atime: UNIX_EPOCH,
mtime: UNIX_EPOCH,
ctime: UNIX_EPOCH,
crtime: UNIX_EPOCH,
kind: FileType::Directory,
perm: 0o755,
nlink: 2,
uid: 1000,
gid: 1000,
rdev: 0,
flags: 0,
blksize: 512,
padding: 0,
};
const DEFAULT_FILE_ATTR: FileAttr = FileAttr {
ino: 2,
size: 4096,
blocks: 1,
atime: UNIX_EPOCH,
mtime: UNIX_EPOCH,
ctime: UNIX_EPOCH,
crtime: UNIX_EPOCH,
kind: FileType::RegularFile,
perm: 0o644,
nlink: 1,
uid: 1000,
gid: 1000,
rdev: 0,
flags: 0,
blksize: 512,
padding: 0,
};
impl Filesystem for RFS {
fn lookup(&mut self, _req: &Request, _parent: u64, name: &OsStr, reply: ReplyEntry) {
if name.to_str() == Some("hello.txt") {
reply.entry(&TTL, &DEFAULT_FILE_ATTR, 0);
} else {
reply.error(ENOENT);
}
}
fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
if ino == 1 {
reply.attr(&TTL, &DEFAULT_DIR_ATTR);
} else {
reply.attr(&TTL, &DEFAULT_FILE_ATTR);
}
}
fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
if ino != 1 {
reply.error(ENOENT);
return;
}
let entries = vec![
(1, FileType::Directory, "."),
(1, FileType::Directory, ".."),
(2, FileType::RegularFile, "hello.txt"),
(1, FileType::Directory, "Test"),
];
for (i, entry) in entries.into_iter().enumerate().skip(offset as usize) {
if reply.add(entry.0, (i + 1) as i64, entry.1, entry.2) {
break;
}
}
reply.ok();
}
}
fn main() {
let mountpoint = "dir";
let options = vec![];
fuser::mount2(RFS, mountpoint, &options).unwrap();
}