FAQ
From fuse
General
How can I umount a filesystem?
FUSE filesystems can be unmounted either with:
umount mountpoint
or
fusermount -u mountpoint
The later does not need root privileges if the filesystem was mounted by the user doing the unmounting.
What's the difference between FUSE and LUFS?
The main difference between them is that in LUFS the filesystem is a shared object (.so) which is loaded by lufsmount, and in FUSE the filesystem is a separate executable, which uses the fuse library. The actual API is very similar, and there's a translator, that can load LUFS modules and run them using the FUSE kernel module (see the lufis package on the FUSE page).
Another difference is that LUFS does some caching of directories and file attributes. FUSE does not do this, so it provides a 'thinner' interface.
By now LUFS development seems to have completely ceased.
Why is it called FUSE? There's a ZX Spectrum emulator called Fuse too.
At the time of christening it, the author of FUSE (the filesystem) hadn't heard of Fuse (the Speccy emulator). Which is ironic, since he knew Philip Kendall, the author of that other Fuse from earlier times. Btw. the author of FUSE (the filesystem) also created a Speccy emulator called Spectemu.
The name wanted to be a clever acronym for "Filesystem in USErspace", but it turned out to be an unfortunate choice. The author has since vowed never to name a project after a common term, not even anything found more than a handful of times on Google.
Is it possible to mount a fuse filesystem from fstab?
Yes, from version 2.4.0 this is possible. The filesystem must adhere to some rules about command line options to be able to work this way. Here's an example of mounting an sshfs filesystem:
sshfs#user@host:/ /mnt/host fuse defaults 0 0
The mounting is performed by the /sbin/mount.fuse helper script. In this example the FUSE-linked binary must be called sshfs and must reside somewhere in $PATH.
Why don't other users have access to the mounted filesystem?
FUSE imposes this restriction in order to protect other users' processes from wandering into a FUSE filesystem that does nasty things to them such as stalling their system calls forever. (See this comment.)
To lift this restriction for all users or for just root, mount the filesystem with the "-oallow_other" or "-oallow_root" mount option, respectively. Non-root users can only use these mount options if "user_allow_other" is specified in /etc/fuse.conf.
It has been argued that allowing users to mount removable media readable by others (as many popular Linux distributions do) presents the same risks and hence there is no point for this FUSE restriction, at least in such distributions.
Licensing issues
Under what license is FUSE released?
The kernel part is released under the GNU GPL.
Libfuse is released under the GNU LGPL.
All other parts (examples, fusermount, etc) are released under the GNU GPL.
Under what conditions may I modify or distribute FUSE?
See the files COPYING and COPYING.LIB in the distribution.
More information can be found at [1]
Under what conditions may I distribute a filesystem which uses libfuse?
See COPYING.LIB in the distribution.
In simple terms as long as you are linking dynamically (the default) there are no limitations on linking with libfuse. For example you may distribute the filesystem itself in binary form, without source code, under any propriatery license.
Under what conditions may I distribute a filesystem that uses the raw kernel interface of FUSE?
There are no restrictions whatsoever for using the raw kernel interface.
API
Which method is called on the close() system call?
flush() and possibly release(). For details see the documentation of these methods in <fuse.h>
Wouldn't it be simpler if there were a single close() method?
No, because the relationship between the close() system call and the release of the file (the opposite of open) is not as simple as people tend to imagine. UNIX allows open files to acquire multiple references
- after fork() two processes refer to the same open file
- dup() and dup2() make another file descriptor refer to the same file
- mmap() makes a memory mapping refer to an open file
This means, that for a single open() system call, there could be more than one close() and possibly munmap() calls until the open file is finally released.
Can I return an error from release()?
No, it's not possible.
If you need to return errors on close, you must do that from flush().
How do I know which is the last flush() before release()?
You can't. All flush() calls should be treated equally. Anyway it wouldn't be worth optimizing away non-final flushes, since it's fairly rare to have multiple write-flush sequences on an open file. The general exception is when a pipe is involved. During pipe construction a pipe a flush() will occur right after the file open(). This flush() may be followed by writes to the file, if any, and then by another flush() before the release().
Why doesn't FUSE forward ioctl() calls to the filesystem?
Because it's not possible: data passed to ioctl() doesn't have a well defined length and structure like read() and write(). Consider using getxattr() and setxattr() instead.
Is there a way to know the uid, gid or pid of the process performing the operation?
Yes: fuse_get_context()->uid, etc.
Why does my filesystem receive getattr() requests if there is no client issuing any getattr() syscalls?
FUSE automatically calls getattr() whenever a new filesystem object has been created (i.e. after open(), create(), link(), symlink() and mkdir() requests). It does so to immediately cache the attributes (ownership,
timestamps, etc.). This is basically an optimization that can not (yet) turned off.
It may also be that the getattr() calls are due to syscalls generated during path resolution (see man 7 path_resolution on linux systems). Basically your system will do a getattr() call for every path component, so when you chdir() into /usr/share/man, you will get getattr() calls for /usr, /usr/share and /usr/share/man.
How should threads be started?
Miscellaneous threads should be started from the init() method. Threads started before fuse_main() will exit when the process goes into the background.
Is it possible to store a pointer to private data in the fuse_file_info structure?
Yes, the 'fh' field is for this purpose. This field may be set in the open() and create() methods, and is available in all other methods having a struct fuse_file_info parameter. Note, that changing the value of 'fh' in any other method as open() or create() will have no affect.
Since the type of 'fh' is unsigned long, you need to use casts when storing and retrieving a pointer. Under Linux (and most other architectures) an unsigned long will be able to hold a pointer.
This could have been done with a union of 'void *' and 'unsigned long' but that would not have been any more type safe as having to use explicit casts. The recommended type safe solution is to write a small inline function that retrieves the pointer from the fuse_file_info structure.
Problems
Version problems
Why do I get Connection Refused after mounting?
Library is too old (< 2.3.0)
You can check which version of the library is being used by foofs by doing ' 'ldd path_to_foofs' . It will return something like this
libfuse.so.2 => /usr/local/lib/libfuse.so.2 (0xb7fc9000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7fb9000)
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0xb7f39000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7e04000)
Then do 'ls -l path_to_libfuse'
> ls -l /usr/local/lib/libfuse.so.2 lrwxrwxrwx 1 root root 16 Sep 26 13:41 /usr/local/lib/libfuse.so.2 -> libfuse.so.2.2.1
Why does fusermount fail with an Unknown option error?
Errors like 'fusermount: Unknown option -o' or 'fusermount: Unknown option --' mean, that an old version of fusermount is being used. You can check by doing 'which fusermount' .
If you installed FUSE from source, then this is probably because there exists a binary package on your system which also contains a fusermount program, and is found first in the path, e.g. in /usr/bin/fusermount.
The solution is to remove the binary package.
What version of FUSE do I need to use FUSE with Linux 2.4?
FUSE 2.5.3 (supports 2.4.21 or later); later versions include a kernel module compatible with Linux 2.6 only (Linux 2.6.9 or later, as of FUSE 2.6.1).
The latest version of the FUSE libraries retains compatibility with the module for 2.4.x .
Installation problems
Why is there an error loading shared libraries?
If you get the following error when starting a FUSE-based filesystem:
foofs: error while loading shared libraries: libfuse.so.2: cannot open shared object file: No such file or directory
check /etc/ld.so.conf for a line containing '/usr/local/lib'. If it's missing, add it, and run ldconfig afterwards.
Why doesn't mounting as user work if installing FUSE from a package?
Distributions often package 'fusermount' without the suid bit, or only executable to the 'fuse' group.
This results in the following message, when trying to mount a filesystem as an unprivileged user:
fusermount: mount failed: Operation not permitted
The simplest solution is to change the mode of 'fusermount':
chmod 4755 /usr/bin/fusermount
Note, you may have to do this after each upgrade.
Other problems
Why are some bytes zeroed when reading a file?
This happens if the filesystem returns a short count from the read() method. If the file wasn't opened in direct I/O mode, the read() method must return exactly the requested number of bytes, unless it's the end of the file.
If the file was opened in direct I/O mode (with direct_io mount option, or by setting the direct_io field of fuse_file_info at open) the read can return a smaller value than requested (but some programs (notably mountlo) mishandle such situation in write and produce broken files). In this case the end of file can be signalled by returning zero.
What do I do if /dev/fuse does not exist?
Maybe the FUSE module is not loaded. As root, try:
modprobe fuse
If nothing changes, as root run:
mknod /dev/fuse c 10 229
What do I do if you don't have access to /dev/fuse?
As root run:
chmod o+rw /dev/fuse
Remember that this will allow ordinary users to mount their own user space filesystems.
If that's not what you want then use different permissions.
Why does cp return operation not permitted when copying a file with no write permissions for the owner?
"cp" calls open(2) with read-only permissions and O_CREAT, the purpose being to atomically obtain a read/write file handle and make the file read-only. Unfortunately, this does not work very well in fuse, since you first get a mknod, and then an open call. At the time of open, you can't distinguish easily wether this is the first open issued by cp, or another process trying to write a read-only file.
Defining the 'create' method solves this problem, however this requires a Linux kernel version of at least 2.6.15 and libfuse version 2.5 or greater (on FreeBSD you'll need fuse4bsd-0.3.0-pre1 or newer for this).
There can be other workarounds, however the easy one is to use the "default_permissions" mount option, and to avoid checking permissions on open. If you store files on a filesystem, this can get tricky because you will have to change the file mode to allow writing. Using the stateful API (i.e. returning an handle on open) will simplify things. In this case, and using "-o default_permissions", when implementing the open call you have to:
1. check if the open is in write mode (i.e. mode has O_RDWR or O_WRONLY)
2. in that case (in mutual exclusion with other open, getattr etc. calls on the same file) change the mode from "M" to "M OR 0o200"
3. open the file, change back the mode even in case of errors, and return the obtained handle
Why doesn't find work on my filesystem?
The st_nlink member must be set correctly for directories to make find work. If it's not set correctly the -noleaf option of find can be used to make it ignore the hard link count (see man find).
The correct value of st_nlink for directories is NSUB + 2. Where NSUB is the number of subdirectories. NOTE: regular-file/symlink/etc entries *do not* count into NSUB, only directories.
If calculating NSUB is hard, the filesystem can set st_nlink of directories to 1, and find will still work. This is not documented behavior of find, and it's not clear whether this is intended or just by accident. But for example the NTFS filesysem relies on this, so it's unlikely that this "feature" will go away.
What is the reason for IO errors?
The kernel part of FUSE returns the EIO error value, whenever the userspace filesystem sends a "bad" reply. Sometimes these are unavoidable, and not necessarily a fault of the filesystem. Possible causes of this are (non-exhaustive)
- the filesystem returned a short count on write().
- the type of the file has changed (e.g. a directory suddenly became a symlink).
- a directory entry contained a filename that was too long (no, ENAMETOOLONG is not the right error here).
- the same node ID value was used for two different directories (i.e. hard-linked directories are not allowed).
- In the GETATTR function, st_mode needs to have a valid filetype bit set, like S_IFREG or S_IFDIR, see the stat manual for more.
I can not know the file size in advance, how do I force EOF from fs_read() to be seen in the application?
Set direct_io in fs_open().
Misc
Can the filesystem ask a question on the terminal of the user?
It would not be possible generally speaking, since it might not be an interactive program but rather a daemon, or a GUI program doing the operation. However you should be able to get the PID for the caller, and by looking in /proc you should be able to find the process tty or something similar.
But this is not recommended. You should rather think about solving this another way.
If a filesystem is mounted over a directory, how can I access the old contents?
There are two possibilities:
The first is to use 'mount --bind DIR TMPDIR' to create a copy of the namespace under DIR. After mounting the FUSE filesystem over DIR, files can still be accessed through TMDIR. This needs root privileges.
The second is to set the working directory to DIR after mounting the FUSE filesystem. For example before fuse_main() do
save_dir = open(DIR, O_RDONLY);
And from the init() method do
fchdir(save_dir); close(save_dir);
Then access the files with relative paths (with newer LIBC versions the *at() functions may also be used instead of changing the CWD).
This method doesn't need root privileges, but only works on Linux (FreeBSD does path resolving in a different way), and it's not even guaranteed to work on future Linux versions.
How do I test my new file system?
There are a number of tools listed here on SourceForge
POSIX testing may be found at POSIX
The ntfs-3g team has made a test suite available at [2] and [3]. See the email fuse archive [4] for more details.
