xref: /haiku/docs/develop/file_systems/userlandfs.rst (revision 084e24d0bf3808808e2bf58d4d65f493bd2b8f49)
1.. _Userland FS Page:
2
3UserlandFS: filesystems in userspace
4####################################
5
6UserlandFS was initially designed as a development tool allowing to run existing filesystems in
7userspace. However, it turns out being able to do that is pretty useful outside of debugging
8sessions too.
9
10UserlandFS can load 3 types of filesystems, which are loaded as add-ons in an userlandfs_server
11process. The process communicates with the kernel side of userlandfs to get the filesystem requests
12and send back the responses.
13
14UserlandFS exposes three different APIs to filesystem add-ons: one compatible with the Haiku kernel,
15one compatible with the BeOS one, and one compatible with FUSE.
16
17The communication between the kernel and userlandfs_server is identical no matter which filesystem
18API is being used. The only differences are in the server itself, which will create an instance of
19the correct subclass of Volume and forward the requests to it.
20
21The FUSE API
22============
23
24FUSE is a similar tool to UserlandFS. It was initially designed for Linux, but, because there are
25many filesystems written for it, it was later ported to MacOS and FreeBSD. The FUSE project in
26itself defines a network-like communication protocol between the kernel and the filesystem, however,
27this is not what is implemented in UserlandFS (which already has its own way to do this part).
28Instead, the provided API is compatible with libfuse (version 2.9.9, since most filesystems
29available for FUSE have not migrated to libfuse 3.x yet).
30
31This means only filesystems using libfuse can easily be ported. Those implementing the FUSE protocol
32in other ways (for example because they are not written in C or C++ and need a different library)
33will not be ported to Haiku as easily.
34
35The libfuse API is actually two different APIs. One is called "fuse_operations". It is a quite
36high level API, where all functions to access files receive a path to the file to operate on, and
37the functions are synchronous. The other API (called "low level") is asynchronous and the files
38are identified by their inode number. Of course, the low level API allows to get better performance,
39because the kernel and userlandfs already work with inode numbers internally. With the high level
40API, the inode number has to be converted back to a filepath everytime a function is called.
41
42Each FUSE filesystem uses one of these two APIs. UserlandFS implements both of them and will
43automatically detect which one to use.
44
45Because of the Linux FUSE design, normally each filesystem is a standalone application, that
46directly establishes communication with the kernel. When built for UserlandFS, the filesystems are
47add-ons instead, so their main() function is called from userlandfs_server after loading the add-on.
48
49We have found that this works reasonably well and it will be possible to run most filesystems
50without any changes to their sourcecode.
51
52When they initialize, FUSE filesystems provide userlandfs with a struct containing function pointers
53for the various FUSE operations they implement. From this table, userlandfs_server detects which
54features are supported, and reports this back to the kernel. Then the kernel-side of userlandfs
55knows to not forward to userspace requests that wouldn't be handled by the filesystem anyway.
56
57FUSE filesystems also usually need some command line options (both custom ones, and standard ones
58forwarded to FUSE initialization options). In Haiku, these are passed as mount options which are
59forwarded to the filesystem add-on when starting it. The add-on main function will be called only
60when a filesystem of the corresponding type is being mounted.
61
62Extensions to the FUSE API
63--------------------------
64
65The FUSE API is missing some things that are possible in Haiku native filesystems. Specifically,
66there is no possibility to implement the "get_fs_info" call, and in particular use it to set
67volume flags. This is especially annoying for networked filesystems, where it is important to mark
68the filesystem as "shared".
69
70Therefore, an extra FUSE "capability" has been added to mark support for this. Capabilities are the
71way FUSE negociates features between the kernel and the filesystem. The kernel tells the filesystem
72which capabilities are supported, and the filesystem tells the kernel which one it wants to use.
73
74If the FUSE_CAP_HAIKU_FUSE_EXTENSIONS capability is enabled, userlandfs will query the filesystem
75info using the ioctl hook of the filesystem, with a command value FUSE_HAIKU_GET_DRIVE_INFO. It
76expects the filesystem to then fill the fs_info structure passed in the ioctl pointer.
77
78Debugging userlandfs
79====================
80
81Because a lot of the code is in userspace, you can simply start userlandfs_server in a terminal to
82get its output, or attach a Debugger to it. There is no timeout for userlandfs requests, so if you
83are debugging something in userlandfs_server, all calls to the filesystem mounted through it will
84simply block until the request thread is running again.
85