zargony / fuse-rs

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

Documentation gaps #67

Open anowell opened 8 years ago

anowell commented 8 years ago

I've been tripping over a few things trying to implement a FUSE network filesystem. I thought I'd jot down some questions, and I'd be happy to turn any answers into some documentation PRs.

  1. mount takes an array of options, but in tinkering with options like noatime, subtype=foo, and ro (various options from fuse and mount man pages). I don't see any change reflected in /etc/mtab. Do I simply misunderstand what options can be specified?
  2. Assuming I can get ro vs rw options to work, would the kernel cease to call write, unlink, etc.., or would the filesystem need to explicitly catch such cases and return EROFS?
  3. What is TTL used for on structs like ReplyEntry? Will the kernel actually cache those for that duration and not make repeated calls to FUSE in that duration?
  4. How does one end up with a filesystem with deferred writes? Currently I commit (via HTTP) on release if modified and no remaining readers, which might be fine, but I'd like to tinker with a commit=n type of setting (to optimize for the case where a file is reopened for writing right after it was closed). Given that the kernel doesn't ever seem to trigger fsync for basic open-write-close usage, I presume I'm left to spin up a thread that handles commits if I really want such a feature.
  5. I often wonder which error cases I need to address in different FUSE functions. For example, ENOTDIR is a documented error for mknod if parent isn't a dir, but does FUSE return that before calling mknod (i.e. by checking attr.kind returned by getattr)?

There are probably others, and perhaps some of these are more about FUSE in general, but definitely things that have been tripping me up. There are plenty of other things that I've had to figure out by experimentation, so I might try to summarize some of that up into PR at some point, because by-and-large this library is incredibly approachable for building a FS from scratch with no previous FUSE experience.

zargony commented 8 years ago

You're right that a lot of documentation is missing, especially for people with less knowledge about file system internals (i.e. the most of us). Documentation of FUSE and OSXFUSE themselves are not very detailed, I'd say (at least far from what we are used to have for crates)

There's plenty of space for improvement here :) The documentation of this crate's interface could be improved, of course. But also general information about Filesystems, how they work, what you need to pay attention to, and more examples would be great to have. Having a sound documentation for beginners to learn about filesystems and start their own and for experts as a reference would be awesome.

I'd love to see new and improved documentation appear for this crate. I'd try to assist to the best of what I've learned about filesystems. (I'm just not the best doc writer since I'm not a native speaker)

zargony commented 8 years ago

1) From what I understand, there are several known mount-options (like noatime and ro) that are handled by the kernel. From what I remember, FUSE also knows a way to pass mount options to the userspace process, but I don't remember how exactly, and as far as I remember, this is currently unsupported in Rust-FUSE. 2) As far as I know, the kernel handles ro/rw. I'm unsure if it is necessary or maybe good practice to also make the fs implementation aware of it 3) Yes. The kernel may (and usually does) cache the information about an inode for up to the ttl you return 4) Yes, such an implementation would work like a block level write cache where a background task is writing changed blocks to the hdd asynchronously. You're just handling http requests instead of a block device. Keep in mind that implementing flush becomes crucial for write-caching filesystems. 5) Yes, several such checks are done by the kernel or FUSE. However I'm not exactly sure which ones (and it might be different for different kernels). Errno meanings are usually well-known by system developers or in general by C programmers. They are usually passed back to the calling process, which displays them, e.g. with libc's perror() or strerror() function.

oconnor663 commented 6 years ago

I think the answer to #1 is that you need to pass an explicit -o string before each option string in the slice you're giving to mount. I've tried to make this more explicit in the docs with https://github.com/zargony/rust-fuse/pull/102.