Re: Using FUSE as an VFS
Posted: Thu Mar 18, 2021 3:44 pm
Please define what you mean by "reentrant", because it's definitely not what we normally do. Allowing one operation at a time is called concurrency (or the lack thereof) sometimes also called exclusive access, and has nothing to do with re-entrancy, like a function or library calling into itself multiple times. For example, multiple tasks are allowed to call the fs task/subsystem, so the syscalls must be written in a way to allow re-entrancy, because there's no guarantee that a previous write call made by another task has finished when another task is calling the same write function, but with different parameters (hence the function must be re-entrant). This is independent to the issue of exclusive access of file system meta data (it might be that all concurrent tasks are writing files on different mount points).rdos wrote:Nothing can solve this if the implementation isn't reentrant, other than only allowing one operation at a time.
Most definitely not the same. A semaphore would block the caller, while a queue allows non-blocking async operations. There's a huge performance difference.rdos wrote:Sure, you can create a queue of commands, but that basically is like putting a semaphore on the whole fuse module.
I'm confused. You wrote "let read/write sector use the file handle" and you write "not just stuff that can be connected to file handles". Which one is it then? BTW, anything can be connected to file handles, that's whole point of the UNIX philosophy. That's exactly what they mean by "everything is a file".rdos wrote:Because it allows me to connect the read-write operations to anything I like, not just stuff that can be connected to file handles.bzt wrote:Now how would that be any different to the POSIX file abstraction, API-wise? There you open the file and you use read/write on the file handle (which then are translated into sector read/writes in the kernel if the handle is for a block device, but that's transparent to you).rdos wrote:Easy. You open the file in your application and let read/write sector use the file handle.
Nope, that's a totally independent issue, fuse or not. Look up mmap and unmap.rdos wrote:Additionally, by using this interface you will always need to copy stuff between the kernel and a user mode buffer.
Okay, now I'm sure you have problems with your i-node definition. A file position is not what an i-node is. It wouldn't even map to i-node numbers either, because file position is unique, and multiple objects in the rar can't have the same position.rdos wrote:In rar, the i-node would be the file position of the object.
How could they be? One is a scalar, the other is a structure. Cluster numbers are just a simple index to an allocation table. They do not identify the file on the disk, they do not tell you if the pointed object is a directory or a file for example. Plus you can't assign the same cluster to multiple paths, that would be a FAT error (with the notable exception of "." and ".."). With i-nodes, it's perfectly fine that more paths share the same i-node (called hard links) by having multiple paths the same i-node number in their directory entries.rdos wrote:Wrong. I-nodes are cluster numbers in FAT.
Exactly.thewrongchristian wrote:But I wouldn't call it an i-node. It doesn't contain what an i-node in a UNIX like OS would contain. FAT has a combined directory entry/i-node structure, meaning there is a 1 to 1 mapping between a directory entry and a file.
I don't know about that. I actually haven't seen any fuse driver that wouldn't check the superblock for magic bytes, but you're right about the fact fuse lacks a common way to identify which driver to call. Right now your only option is to call all drivers one after another and see which one isn't failing. Not very optimal, however only needed to do once when mounting, then you can cache the driver's pointer. (Alternatively you could port libmagic and assign a magic definition to each and every ported fuse driver. Then you could use libmagic to select the appropriate fuse driver)thewrongchristian wrote:Identifying files. The FUSE operations tend to identify files by name.
Well, this isn't something that fuse could do anything about. Whether a fuse driver is stateless or not, is totally up to the driver, fuse has no say in that matter.thewrongchristian wrote:Related to above, I want my FUSE interface to be stateless
It does not. How a fuse driver caches path is totally up to the fuse driver. A FAT driver could use directory entry offsets as "handle" if they wish to do so. Fuse drivers with better performance tend to utilize the underlying storage device's bio_io_vec feature in the Linux kernel (so the fuse driver essentially create a command list what to read/write and from/to, and it sends that list to the kernel, not the data, nor the fuse-driver internal "handle" or id).thewrongchristian wrote:I'd have to check, but I'm not sure this handle goes back and forth over the protocol/API in FUSE.
No, it's configurable. It's just a VFS layer, so it just proxies the read/write commands, tells the kernel where to access it, but does not copy the data. See direct_io. But you could copy the data from a fuse driver if you want to (for example, like reading compressed contents from a zip archive would require the fuse driver to uncompress and return that uncompressed buffer rather than telling the kernel where the compressed data can be found). Again, this is totally up to the fuse driver.thewrongchristian wrote:Buffer sharing. I think the FUSE protocol sends buffer contents over the FUSE channel, rather than using some shared memory mechanism.
Doesn't matter. Fuse uses LGPL, which means you can link that with your code no matter your code's license.thewrongchristian wrote:Licensing. I've not decided what license to use for my kernel, as and when I "release" it.
Even though you are thinking this for the wrong reasons, this is generally a very good idea.rdos wrote:I'll create my own interface and then provide a FUSE layer on top of it.
Cheers,
bzt