zargony / fuse-rs

Rust library for filesystems in userspace (FUSE)
MIT License
1.07k stars 130 forks source link

WIP: Modernize (continued) #126

Open zargony opened 5 years ago

zargony commented 5 years ago

Next (second) step towards a more modern architecture and idiomatic interfaces. First step happened in #125.

TODO:

EricTheMagician commented 4 years ago

Hi @zargony Do you have any additional thoughts about implementing async/await?

I'm new to Rust and would like to learn it, especially the async/await pattern. I'd like to contribute this feature to this project, but just wanted to check in with you before I get started.

Edit: Do you actually need libfuse? It seems like everything is already implemented in rust and the only reason you use libfuse is to mount the filesystem. Is it possible to just implement that section in rust and forget about libfuse as a dependency?

zargony commented 4 years ago

Sadly I didn't get much time over christmas to work on fuse-rs. This branch is basically well prepared for async/await. It's still missing some essential functionality like the session loop (WIP in last commit) and the Directory reply type. But with the changes introduced in this branch, it should be pretty straight-forward to enable async/await by simply making most handler methods async. One problem though is, that we can't have async methods in traits yet. To work around that we could either use the async-trait crate or have associated types for returned futures.

Unfortunately using async on the underlying kernel communication currently means that we have to choose a runtime that handles the RawFd communication. I'd rather be runtime agnostic in a library like fuse-rs but unfortunately that doesn't seem to be possible for now. I did some tests with async-std which provides easy async RawFd reading/writing like std does and it worked fine. I'm not sure though how we can / want to support tokio or even other runtimes.

You're right that libfuse is only used for mounting the filesystem. I'd like to remove that dependency as well (there has been talk about adding a feature flag for libfuse in another issues). Although this means that we either need to recreate a fuse_mount function in fuse-rs or rely on calling an external helper like fusermount. Both doesn't seem trivial since it behaves differently on various systems and nobody took the time to explore that yet.

EricTheMagician commented 4 years ago

For removing libfuse, do you have sources for fuse behaving differently on different systems? What are the known behaviours?

I did look in to and the main code from libfuse is here: https://github.com/libfuse/libfuse/blob/master/lib/mount.c#L384

and the fallback to fusermount is here: https://github.com/libfuse/libfuse/blob/master/lib/mount.c#L307

At least for the main mounting mechanism, it ultimiately relinquishes mounting to libc::mount http://man7.org/linux/man-pages/man2/mount.2.html

When I implemented it (I did it in the master branch by mistake), mounting the example filesystems worked and behaved normally. I hadn't implemented the fallback to fusermount, but it looks straightforward to do. I did start re-implementing it in the modernize branch, but I don't have as much time right now.

To completely remove libfuse as a dependency, we would need to reimplement fusermount in rust.

I hope this research helps someone