fuse-rs icon indicating copy to clipboard operation
fuse-rs copied to clipboard

There should be fusexmp-like example

Open vi opened this issue 10 years ago • 10 comments

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.

vi avatar Nov 11 '15 17:11 vi

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.

zargony avatar Jan 31 '16 21:01 zargony

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].

vi avatar Feb 01 '16 01:02 vi

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?

oleid avatar May 18 '16 21:05 oleid

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.

vi avatar May 18 '16 21:05 vi

@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.

cuviper avatar May 18 '16 21:05 cuviper

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.

oleid avatar May 18 '16 21:05 oleid

@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.

oleid avatar May 18 '16 22:05 oleid

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.

cuviper avatar May 18 '16 22:05 cuviper

You're absolutely right, thanks a lot!

oleid avatar May 19 '16 06:05 oleid

Started doing the xmp.rs example which is expected to work like fusexmp (uses usual Rust std::fs operations). readdir already works.

vi avatar Dec 01 '19 23:12 vi