Filesystem in Userspace

Mailing list archives on SourceForge

Mailing list archives on  GMane

Subscribe mailing list

SourceForge project page

Language bindings

Filesystems based on FUSE

Supported Operating Systems




With FUSE it is possible to implement a fully functional filesystem in a userspace program.  Features include:

  • Simple library API
  • Simple installation (no need to patch or recompile the kernel)
  • Secure implementation
  • Userspace - kernel interface is very efficient
  • Usable by non privileged users
  • Runs on Linux kernels 2.4.X and 2.6.X
  • Has proven very stable over time

FUSE was originally developed to support AVFS but it has since became a separate project.  Now quite a few other projects are using it.  Implementing a filesystem is simple,  a hello world filesystem is less than a 100 lines long.  Here's a sample session:

~/fuse/example$ mkdir /tmp/fuse
~/fuse/example$ ./hello /tmp/fuse
~/fuse/example$ ls -l /tmp/fuse
total 0
-r--r--r-- 1 root root 13 Jan 1 1970 hello
~/fuse/example$ cat /tmp/fuse/hello
Hello World!
~/fuse/example$ fusermount -u /tmp/fuse


Some projects include the whole FUSE package (for simpler installation).  In other cases or just to try out the examples FUSE must be installed first.  The installation is simple, after unpacking enter:

> ./configure
> make
> make install

If this produces an error, please read on.

The configure script will try to guess the location of the kernel source.  In case this fails, it may be specified using the --with-kernel  parameter.   Building the kernel module needs a configured kernel source tree matching the running kernel.  If you build your own kernel this is no problem.  On the other hand if a precompiled kernel is used, the kernel headers used by the FUSE build process must first be prepared.  There are two possibilities:

  1. A package containing the kernel headers for the kernel binary is available in the distribution (e.g. on Debian it's the kernel-headers-X.Y.Z package for kernel-image-X.Y.Z)
  2. The kernel source must be prepared:
    • Extract the kernel source to some directory
    • Copy the running kernel's config (usually found in /boot/config-X.Y.Z) to .config at the top of the source tree
    • Run make prepare

Trying it out

After installation, you can try out the filesystems in the example directory.  To see what is happening try adding the -d option.  This is the output produced by running cat /tmp/fuse/hello in another shell:

~/fuse/example> ./hello /tmp/fuse -d
unique: 2, opcode: LOOKUP (1), ino: 1, insize: 26
LOOKUP /hello
INO: 2
unique: 2, error: 0 (Success), outsize: 72
unique: 3, opcode: OPEN (14), ino: 2, insize: 24
unique: 3, error: 0 (Success), outsize: 8
unique: 4, opcode: READ (15), ino: 2, insize: 32
READ 4096 bytes from 0
READ 4096 bytes
unique: 4, error: 0 (Success), outsize: 4104
unique: 0, opcode: RELEASE (18), ino: 2, insize: 24

More operations can be tried out with the fusexmp example filesystem.  This just mirrors the root directory similarly to mount --bind / /mountpoint.  This is not very useful in itself, but can be used as template for creating a new filesystem.

By default FUSE filesystems run multi-threaded.  This can be verified by entering the mountpoint recursively in the fusexmp filesystem.  Multi-threaded operation can be disabled by adding the -s option.

Some options can be passed to the FUSE kernel module and the library.  See the output of fusexmp -h for the list of these options.

How does it work?

The following figure shows the path of a filesystem call  (e.g. stat) in the above hello world example:

FUSE structure

The FUSE kernel module and the FUSE library communicate via a special file descriptor which is obtained by opening /dev/fuse.  This file can be opened multiple times, and the obtained file descriptor is passed to the mount syscall, to match up the descriptor with the mounted filesystem.

Hosted at: SourceForge.net Logo