mirror of https://github.com/mkerrisk/man-pages
fuse.4: New page describing /dev/fuse
This is my writeup of a basic description of /dev/fuse after playing with it for a few hours today. It is of course woefully incomplete, and since I neither have a use case nor am working on this code, I will not be in a position to expand it in the near future. However, I'm hoping this could still serve as a handy reference for others looking at this interface. Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
e6f1b08f55
commit
5963519cfe
|
@ -0,0 +1,484 @@
|
|||
.\" Copyright (c) 2016 Julia Computing Inc, Keno Fischer
|
||||
.\" Description based on include/uapi/fuse.h and code in fs/fuse
|
||||
.\"
|
||||
.\" %%%LICENSE_START(VERBATIM)
|
||||
.\" Permission is granted to make and distribute verbatim copies of this
|
||||
.\" manual provided the copyright notice and this permission notice are
|
||||
.\" preserved on all copies.
|
||||
.\"
|
||||
.\" Permission is granted to copy and distribute modified versions of this
|
||||
.\" manual under the conditions for verbatim copying, provided that the
|
||||
.\" entire resulting derived work is distributed under the terms of a
|
||||
.\" permission notice identical to this one.
|
||||
.\"
|
||||
.\" Since the Linux kernel and libraries are constantly changing, this
|
||||
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
||||
.\" responsibility for errors or omissions, or for damages resulting from
|
||||
.\" the use of the information contained herein. The author(s) may not
|
||||
.\" have taken the same level of care in the production of this manual,
|
||||
.\" which is licensed free of charge, as they might when working
|
||||
.\" professionally.
|
||||
.\"
|
||||
.\" Formatted or processed versions of this manual, if unaccompanied by
|
||||
.\" the source, must acknowledge the copyright and authors of this work.
|
||||
.\"
|
||||
.\" This man page incorporates parts of the fuse.h header, which is distributed
|
||||
.\" under the following license. No claim is made as to whether or not the
|
||||
.\" below notice is required or whether the parts used in this manual page
|
||||
.\" constitute fair use in applicable jurisdictions.
|
||||
.\"
|
||||
.\" Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" %%%LICENSE_END
|
||||
.\"
|
||||
.TH FUSE 4 2016-12-10 "Linux" "Linux Programmer's Manual"
|
||||
.SH NAME
|
||||
/dev/fuse \- Filesystem in Userspace (FUSE) device
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B #include <linux/fuse.h>
|
||||
.nf
|
||||
.SH DESCRIPTION
|
||||
|
||||
This device is the primary interface between the FUSE filesystem driver
|
||||
and a userspace process wishing to provide the file system (referred to
|
||||
in the rest of this manual page as the
|
||||
.I file system daemon.
|
||||
This manual page is intended for those
|
||||
interested in understanding the kernel interface
|
||||
itself. Those implementing a FUSE filesystem may wish to make use of
|
||||
a userspace library such as libfuse that abstracts away the low level
|
||||
interface.
|
||||
|
||||
At its core, FUSE is a simple client-server protocol, in which the Linux
|
||||
kernel is the client and the daemon is the server. After obtaining
|
||||
a file descriptor to this device, the daemon may
|
||||
.BR read (2)
|
||||
requests from that file descriptor and is expected to
|
||||
.BR write (2)
|
||||
back its replied. It is important to note, that a file descriptor is
|
||||
associated to a unique FUSE file system. In particular, opening a
|
||||
second copy of this device, will not allow access to resources created
|
||||
through the first file descriptor (and vice versa).
|
||||
|
||||
.SS The basic protocol
|
||||
Every message that is read by the daemon begins with a header described by
|
||||
the following struct:
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_in_header {
|
||||
uint32_t len; /* Total length of the data, including this header */
|
||||
uint32_t opcode; /* The kind of operation (described below) */
|
||||
uint64_t unique; /* A unique identifier for this request */
|
||||
uint64_t nodeid; /* The id of the filesystem object being operated on */
|
||||
uint32_t uid; /* The uid of the requesting process */
|
||||
uint32_t gid; /* The gid of the requesting process */
|
||||
uint32_t pid; /* The pid of the requesting process */
|
||||
uint32_t padding;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
followed by a variable length data portion (which may be empty) specific to the requested operation
|
||||
(the requested operation is indicated by
|
||||
.I opcode
|
||||
).
|
||||
|
||||
The daemon should then process the request and if applicable send a reply (almost
|
||||
all operations require a reply - if they do not this is documented below), by
|
||||
performing a
|
||||
.BR write(2)
|
||||
to the file descriptor. All replies must start with the following header:
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_out_header {
|
||||
uint32_t len; /* Total length of data written to the fd */
|
||||
int32_t error; /* Any error that occurred (0 if none) */
|
||||
uint64_t unique; /* The value from the corresponding request */
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
again followed by (potentially empty) variable sized data depending on the
|
||||
executed request. However, if the reply is an error reply (i.e. error is set),
|
||||
then no further payload data should be sent, independent of the request.
|
||||
|
||||
.SS Exchanged messages
|
||||
|
||||
This section should contain documentation for each of the messages in the protocol.
|
||||
This manual page is currently incomplete, so not all messages are documented. For
|
||||
each message, first the struct sent by the kernel is given, followed by a description of the semantics of the message.
|
||||
|
||||
.TP
|
||||
.BR FUSE_INIT " ( 25 )"
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_init_in {
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t max_readahead; /* Since protocol v7.6 */
|
||||
uint32_t flags; /* Since protocol v7.6 */
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
This is the first request sent by the kernel to the daemon. It is used to
|
||||
negotiate the protocol version and other file system parameters. Note that
|
||||
the protocol version may affect the layout of any structure in the protocol
|
||||
(including this one). The daemon must thus remember the negotiated version
|
||||
and flags for each session. As of the writing of this man page, the highest
|
||||
supported kernel protocol version is
|
||||
.I 7.26.
|
||||
|
||||
Users should be aware that the descriptions in this manual page
|
||||
may be incomplete or incorrect for older or more recent protocol versions.
|
||||
|
||||
The reply format for this request is
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_init_out {
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t max_readahead; /* Since v7.6 */
|
||||
/* field exists since v7.6 - certain flags were introduced
|
||||
in later versions */
|
||||
uint32_t flags;
|
||||
uint16_t max_background; /* Since v7.13 */
|
||||
uint16_t congestion_threshold; /* Since v7.13 */
|
||||
uint32_t max_write; /* Since v7.5 */
|
||||
uint32_t time_gran; /* Since v7.6 */
|
||||
uint32_t unused[9];
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
If the major version supported by the kernel, is larger than that supported
|
||||
by the daemon, the reply shall consist of only
|
||||
.I uint32_t major
|
||||
(following the usual header), indicating the largest major version supported
|
||||
by the daemon. The kernel will then issue a new
|
||||
.I FUSE_INIT
|
||||
request conforming to the older version. In the reverse case, the daemon should
|
||||
quietly fall back to the kernel's major version.
|
||||
|
||||
The negotiated minor version is considered to be the minimum of the minor versions
|
||||
provided by the daemon and the kernel and both parties should use the protocol
|
||||
corresponding to said minor version.
|
||||
|
||||
.TP
|
||||
.BR FUSE_GETATTR " ( 3 )"
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_getattr_in {
|
||||
uint32_t getattr_flags;
|
||||
uint32_t dummy;
|
||||
uint64_t fh; /* Only set if (getattr_flags & FUSE_GETATTR_FH)
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
As usual, the filesystem object operated on is indicated by
|
||||
.I header->nodeid.
|
||||
The daemon should compute the attributes
|
||||
of this object and reply with the following message:
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_attr {
|
||||
uint64_t ino;
|
||||
uint64_t size;
|
||||
uint64_t blocks;
|
||||
uint64_t atime;
|
||||
uint64_t mtime;
|
||||
uint64_t ctime;
|
||||
uint32_t atimensec;
|
||||
uint32_t mtimensec;
|
||||
uint32_t ctimensec;
|
||||
uint32_t mode;
|
||||
uint32_t nlink;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint32_t rdev;
|
||||
uint32_t blksize;
|
||||
uint32_t padding;
|
||||
};
|
||||
struct fuse_attr_out {
|
||||
/* Attribute cache duration (seconds + nanoseconds) */
|
||||
uint64_t attr_valid;
|
||||
uint32_t attr_valid_nsec;
|
||||
uint32_t dummy;
|
||||
struct fuse_attr attr;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The fields of
|
||||
.I struct fuse_attr
|
||||
describe the attributes of the required file. For the interpretation
|
||||
of these fields, see
|
||||
.BR stat(2)
|
||||
|
||||
.TP
|
||||
.BR FUSE_ACCESS " ( 34 )"
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_access_in {
|
||||
uint32_t mask;
|
||||
uint32_t padding;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
If the
|
||||
.I default_permissions
|
||||
mount options is not used, this request may be used for permissions
|
||||
checking. No reply data is expected, but errors may be indicated
|
||||
as usual in the reply header (in particular, access denied errors
|
||||
may be indicated, by setting such field to
|
||||
.I -EACCES
|
||||
)
|
||||
|
||||
.TP
|
||||
.BR FUSE_OPEN " ( 14 ) and " FUSE_OPENDIR " ( 34 )"
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_open_in {
|
||||
uint32_t flags; /* The flags that were passed to the open(2) */
|
||||
uint32_t unused;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The requested operation is to open the node indicated by
|
||||
.I header->nodeid
|
||||
the exact semantics of what this means will depend on the
|
||||
filesystem being implemented. However, at the very least the
|
||||
file system should validate that the requested
|
||||
.I flags
|
||||
are valid for the indicated resource and then reply with
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
|
||||
struct fuse_open_out {
|
||||
uint64_t fh;
|
||||
uint32_t open_flags;
|
||||
uint32_t padding;
|
||||
};
|
||||
|
||||
.fi
|
||||
.in
|
||||
|
||||
where
|
||||
.I fh
|
||||
is an opaque identifier that the kernel will use to refer
|
||||
to this resource and open_flags is a bitfield of any number of
|
||||
.B FOPEN_*
|
||||
flags, which indicate properties of this file handle to the kernel.
|
||||
|
||||
.TP
|
||||
.BR FUSE_READ " ( 15 ) and " FUSE_READDIR " ( 28 )"
|
||||
.in +4n
|
||||
.nf
|
||||
|
||||
struct fuse_read_in {
|
||||
uint64_t fh;
|
||||
uint64_t offset;
|
||||
uint32_t size;
|
||||
uint32_t read_flags;
|
||||
uint64_t lock_owner;
|
||||
uint32_t flags;
|
||||
uint32_t padding;
|
||||
};
|
||||
|
||||
.fi
|
||||
.in
|
||||
|
||||
The requested action, it to read up to
|
||||
.I size
|
||||
bytes of the file or directory, starting at
|
||||
.I offset
|
||||
the bytes should be returned directly following the out header,
|
||||
with no further special out structure.
|
||||
|
||||
.TP
|
||||
.BR FUSE_INTERRUPT " ( 36 )"
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_interrupt_in {
|
||||
uint64_t unique;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The requested action is to cancel the pending operation indicated by
|
||||
.I unique
|
||||
This request requires no response. However, receipt of this message does
|
||||
not by itself cancel the indicated operation. The kernel will still expect
|
||||
a reply to said operation (e.g. an EINTR error or a short read). At most
|
||||
one
|
||||
.B FUSE_INTERRUPT
|
||||
request will be issued for a given operation. After issuing said operation,
|
||||
the kernel will wait uninterrutably for completion of the indicated request.
|
||||
|
||||
.TP
|
||||
.BR FUSE_LOOKUP " ( 1 )"
|
||||
|
||||
Directly following the header is a filename to be looked up in the directory
|
||||
indicated by
|
||||
.I header->nodeid.
|
||||
The expected reply is of the form
|
||||
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_entry_out {
|
||||
uint64_t nodeid; /* Inode ID */
|
||||
uint64_t generation; /* Inode generation: nodeid:gen must
|
||||
be unique for the fs's lifetime */
|
||||
uint64_t entry_valid;
|
||||
uint64_t attr_valid;
|
||||
uint32_t entry_valid_nsec;
|
||||
uint32_t attr_valid_nsec;
|
||||
struct fuse_attr attr;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The interpretation of timeouts and
|
||||
.I attr
|
||||
is as in
|
||||
.B FUSE_GETATTR
|
||||
|
||||
.TP
|
||||
.BR FUSE_FLUSH " ( 36 )"
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_flush_in {
|
||||
uint64_t fh;
|
||||
uint32_t unused;
|
||||
uint32_t padding;
|
||||
uint64_t lock_owner;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The requested action is to flush any pending changes to the indicated
|
||||
file handle. No reply data is expected. However, an empty reply message
|
||||
still needs to be issued once the flush operation is complete.
|
||||
|
||||
.TP
|
||||
.BR FUSE_RELEASE " ( 18 ) and " FUSE_RELEASEDIR " ( 29 )"
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_release_in {
|
||||
uint64_t fh;
|
||||
uint32_t flags;
|
||||
uint32_t release_flags;
|
||||
uint64_t lock_owner;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
The counter operation to
|
||||
.BR FUSE_OPEN
|
||||
or
|
||||
.BR FUSE_OPENDIR
|
||||
respectively. The daemon may now free any resources associated with the
|
||||
file handle
|
||||
.I fh
|
||||
as the kernel will no longer refer to it. There are no reply data associated
|
||||
with this request, but a reply still needs to be issued once the request has
|
||||
been completely processed.
|
||||
|
||||
.TP
|
||||
.BR FUSE_STATFS " ( 17 )"
|
||||
This operation implements
|
||||
.BR statfs(2)
|
||||
for this file system. There is no input data associated with this request.
|
||||
The expected reply data has the following structure:
|
||||
.in +4n
|
||||
.nf
|
||||
struct fuse_kstatfs {
|
||||
uint64_t blocks;
|
||||
uint64_t bfree;
|
||||
uint64_t bavail;
|
||||
uint64_t files;
|
||||
uint64_t ffree;
|
||||
uint32_t bsize;
|
||||
uint32_t namelen;
|
||||
uint32_t frsize;
|
||||
uint32_t padding;
|
||||
uint32_t spare[6];
|
||||
};
|
||||
struct fuse_statfs_out {
|
||||
struct fuse_kstatfs st;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
|
||||
For the interpretation of these fields, see
|
||||
.BR statfs(2).
|
||||
|
||||
.SH ERRORS
|
||||
|
||||
.B EPERM
|
||||
Returned from operations on a
|
||||
.I /dev/fuse
|
||||
file descriptor that has not been mounted
|
||||
|
||||
.B EIO
|
||||
Returned from
|
||||
.BR read(2)
|
||||
operations when the kernel's request is too large for the provided buffer.
|
||||
|
||||
.IR Note :
|
||||
There are various ways in which incorrect use of these interfaces can cause
|
||||
operations on the provided filesystem's files and directories to fail with
|
||||
.BR EIO.
|
||||
A partial list of such incorrect uses is
|
||||
changing
|
||||
.I mode & S_IFMT
|
||||
for an inode that has previous been reported to the
|
||||
kernel; or giving replies to the kernel that are shorter than what the kernel
|
||||
expected.
|
||||
|
||||
.B EINVAL
|
||||
Returned from
|
||||
.BR write(2)
|
||||
if validation of the reply failed. Note all mistakes in replies will be caught
|
||||
by this validation. However, basic mistakes, such as short replies or an incorrect
|
||||
.I unique
|
||||
value.
|
||||
|
||||
.B E2BIG
|
||||
Returned from
|
||||
.BR read(2)
|
||||
operations when the kernel's request is too large for the provided buffer
|
||||
and the request was FUSE_SETXATTR.
|
||||
|
||||
.B ENODEV
|
||||
Returned from either operation if the FUSE file system was unmounted.
|
Loading…
Reference in New Issue