Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update FUSE kernel ABI #97

Merged
merged 1 commit into from
Mar 24, 2019
Merged

Update FUSE kernel ABI #97

merged 1 commit into from
Mar 24, 2019

Conversation

zargony
Copy link
Owner

@zargony zargony commented Sep 19, 2017

Update to use FUSE kernel ABI 7.19 which opens up the possibility to support more desired features like better optimization, ioctl and polling/notifications. This will raise the requirements to FUSE 2.9.1 or later on Linux and OSXFUSE 3.0.0 or later on macOS.
There are even newer ABI versions, but 7.19 seems to be the one most commonly supported by various systems.

src/kernel.rs Outdated
pub const FUSE_BIG_WRITES: u32 = 1 << 5; // since ABI 7.9: filesystem can handle write size larger than 4kB
pub const FUSE_DONT_MASK: u32 = 1 << 6; // since ABI 7.12: don't apply umask to file mode on create operations
#[cfg(not(target_os = "macos"))]
pub const FUSE_SPLICE_WRITE: u32 = 1 << 7; // since ABI 7.14: kernel supports splice write on the device
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Splice would be really neat!

src/request.rs Outdated
unimplemented!()
},
FUSE_BATCH_FORGET => {
unimplemented!()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need help with the implementation?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Help would be very welcome of course. I'm just pondering because I'd like to overhaul the overall interface to be more idiomatic and more flexible (especially considering async io) and I don't know if that shouldn't be done first. Batch forget might be more or less easy, but I don't know if I would want the whole notification stuff in the current state

@Mic92
Copy link
Contributor

Mic92 commented Oct 4, 2017

I currently selectively implement some fuse methods as needed by my implementation.
Feel free to pickup code, if you find something useful: https://github.com/Mic92/rust-fuse/commits/cntrfs

@Mic92
Copy link
Contributor

Mic92 commented Oct 4, 2017

I also working on a feature-complete passthrough filesystem: https://github.com/Mic92/cntr/blob/master/src/fs.rs
This could serve as an example for rust-fuse maybe. I want to pass as much as possible tests from xfstests.

@Mic92
Copy link
Contributor

Mic92 commented Oct 5, 2017

Do you see any use for this? Mic92@9c53b9f I made libfuse optional, since I needed low-level access to mount stuff across container namespaces. It will also make my project easier to cross-compile.

@zargony
Copy link
Owner Author

zargony commented Oct 6, 2017

Thanks! Making libfuse optional sounds like a nice idea. It would be nice if we could get rid of the libfuse dependency completely one day, but that'd require to reimplement the mount function (which turned out to be more complicated that I thought when I had a look last time).

A passthrough filesystem would be a great example but also a great reference for people to see how it works. Plus we could perform benchmarks comparisons of the passthrough vs direct filesystem to determine the FUSE overhead (maybe even compare it to a libfuse implementation to see how it performs)

@Mic92
Copy link
Contributor

Mic92 commented Oct 6, 2017

I will do benchmarks anyway for my paper in the next two weeks. Implementing mount was easy in my case. The main purpose of fusemount on linux is to have a dedicated setuid wrapper for mount. However in my case I have to start as root anyway for other reasons.

@Mic92
Copy link
Contributor

Mic92 commented Oct 11, 2017

Batch forget is also now implemented.

@Mic92
Copy link
Contributor

Mic92 commented Oct 18, 2017

I partly support Fuse API 26, the following is missing: FUSE_INTERRUPT, FUSE_POLL, FUSE_NOTIFY_REPLY, CUSE_INIT

@Mic92
Copy link
Contributor

Mic92 commented Oct 20, 2017

Some preliminary performance results from ec2. Performance still sucks since I have not finished multi-threading / splice read/write https://openbenchmarking.org/result/1710208-AL-MERGE427034

Currently the full benchmark suite is running. That discussion might be also of interest: hanwen/go-fuse#192 (comment)

@Mic92
Copy link
Contributor

Mic92 commented Nov 2, 2017

I have now some optional hacky support for splice read/write. (hacky in the sense that there could be less code duplication)

@hanwen
Copy link

hanwen commented Nov 5, 2017

I would avoid support for FUSE_POLL. If rust ever gets built-in support for polling file handles (which Go has), this may complicate writing tests. See hanwen/go-fuse#165

@zargony zargony force-pushed the abi_update branch 2 times, most recently from 42f910d to ab85b81 Compare August 8, 2018 00:16
@zargony
Copy link
Owner Author

zargony commented Aug 8, 2018

Rebased and updated.

After splitting kernel ABI and libfuse FFI stuff into a fuse-sys crate, I was able to select different ABI versions by using cargo features. It's not the most beatiful code (especially the version constant definition looks ugly now), but hopefully it's still readable. Using cargo features works ok to some degree for versioning types and constants and doesn't require huge code duplications like with separate modules or crates per ABI version.
This should probably be better covered by tests, but creating tests for every ABI version is a very tedious task.

This should allow us to have at least ABI and FFI definitions for more recent FUSE versions. How different versions can/should be supported in the fuse crate, is however still open.

@Mic92
Copy link
Contributor

Mic92 commented Aug 8, 2018

In the evaluation part there a performance analysis: https://www.usenix.org/conference/atc18/presentation/thalheim

@ghost
Copy link

ghost commented Sep 17, 2018

I found this thread while looking for docs around implementing notify functions.... any progress on this front?

@piranna
Copy link

piranna commented Sep 27, 2018

I'm also interested on that, specially the new support to mount filesystems by plain users added in Linux 4.18. Is that supported?

@dns2utf8
Copy link

I am using Arch Linux with the 4.19 and soon 4.20 kernel.
Any news on this? Or is no change needed?
Since I am here and ask questions, I see the development is still going on do you plan a release soon?

@Mic92
Copy link
Contributor

Mic92 commented Dec 26, 2018

The fuse protocol is versioned and the linux kernel will supports older versions practically for ever. Newer version of the protocol will only add new features, which are then not accessible to the user of this library.

@Mic92
Copy link
Contributor

Mic92 commented Dec 26, 2018

Since rust-fuse uses fusermount it should be also possible to mount filesystems as unprivileged user.

@Mic92
Copy link
Contributor

Mic92 commented Dec 26, 2018

Mhm. Rust-fuse still uses the old symbol from fuse2 to mount the filesystem, so I am not sure if the fuse3 unprivileged mode would work. In my fork I removed the need for libfuse when mounting that but I require in my project root for different reason, which is why I did not implement unprivileged mounting with linux namespaces.

@zargony zargony merged commit 0933823 into master Mar 24, 2019
zargony added a commit that referenced this pull request Mar 24, 2019
@zargony zargony deleted the abi_update branch March 24, 2019 19:13
@zargony
Copy link
Owner Author

zargony commented Mar 29, 2019

There's ongoing effort to take advantage of a newer ABI and support notify and other functions in #122.

About fuse3 unprivileged mode: fuse_mount_compat25 is used because it returns a plain fd while newer functions return structs like fuse_chan that I wanted to avoid because I'm not sure if their memory layout is guaranteed. As far as I remember, fuse_mount calls fuse_mount_compat25 internally, so there shouldn't be a difference. I'm not very familiar with the mounting process since I always tried to actually get rid of it to become independent from libfuse, but if there's an advantage in using fuse3 functions, I'm open to it (please create a separate issue)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants