fuse-rs
fuse-rs copied to clipboard
There should be fusexmp-like example
I typically use fusexmp.c or fusexmp_fh.c as a template for creating new FUSE filesystems.
It allows to mostly avoid dealing with documentation.
Here I see only short hello and even shorter null examples. Although hello can be recrafted to something usable, it would be nice to have exhaustive example showing all possible calls.
In particular, fusexmp-like example is useful for creating simple FUSE wrappers that do leave all files as is, but .... Trying to create that from scratch makes easy to miss problems like missing extended attributes handling.
I agree that such a template would be nice. I always wanted to write a mirror example (a fuse fs that simply mirrors another existing path). This sounds similar to the template you mentioned. Unfortunately I didn't create one yet.
I started one, discovered that it is like hello_ll.c (while I've got used to fusexmp.c), discovered that unlike in fusexmp.c inode actually does matter, continued writing mirror.rs anyway using map from inode to pathname and back, but then my open source attention lease ran dry and the project stalled...
Maybe I resume it [someday].
On that matter, I'm somehow struggling implementing writes. Although I added the functions "open" and "write", I get "Function not implemented" on calling
LC_ALL=C dd if=/dev/zero of=test/hello.txt count=1
Strace tells me:
open("test/hello.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOSYS (Function not implemented)
fn open(&mut self, _req: &Request, _ino: u64, _flags: u32, reply: ReplyOpen)
{
let file_handle=32;
println!("open: _ino={}, _flags={}", _ino, _flags);
if _ino == 2 {
reply.opened(file_handle, 3);
} else {
reply.error(ENOENT);
}
}
The output is:
open: _ino=2, _flags=32769
I return 3 here, since this is the result I get when dd-ing to a real drive. But no matter what I tried else, the result is the same.
Is this a parameter issue, or might something else be wrong?
Maybe try to just omit implementation of open? hello example does not use it. Also the problem may be in lookup or getattr - they are essential.
@oleid, the resulting file descriptor will probably be 3 indeed, following 0=stdin, 1=stdout, 2=stderr. But as a fuse author you don't get to choose the file descriptor -- this is assigned by the kernel according to whatever that calling process has available.
The parameter where you wrote 3 is actually for flags, fn opened (self, fh: u64, flags: u32), so 3 with the first two bits set is like FOPEN_KEEP_CACHE | FOPEN_DIRECT_IO.
I'm not sure why you'd get ENOSYS though.
So far, I'm using the code from the hello example + open + write. According to strace, open is called (which makes sense) . Thus, I tried to implement it.
@cuviper : right, strace shows the handle doh- how could I forget. Additionally to "3", also tried "0", like the default implementation in the trait. But that also lead to ENOSYS.
OK, I think it's dd's O_TRUNC causing the issue, which you can try avoiding with dd conv=notrunc. When opening with truncation, fuse will also call your setattr with size 0, and I'll bet that's your ENOSYS.
You're absolutely right, thanks a lot!
Started doing the xmp.rs example which is expected to work like fusexmp (uses usual Rust std::fs operations). readdir already works.