From: Keno Fischer <keno-9DCaDmOhoh+8M3too/+dENBPR1lH4CV8@public.gmane.org>
To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Miklos Szeredi <miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org>,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
nikolaus-BTH8mxji4b0@public.gmane.org
Subject: [PATCH] fuse.4: Add new file describing /dev/fuse
Date: Sat, 10 Dec 2016 02:20:18 -0500 [thread overview]
Message-ID: <20161210072018.GA5267@juliacomputing.com> (raw)
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.
---
man4/fuse.4 | 484 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 484 insertions(+)
create mode 100644 man4/fuse.4
diff --git a/man4/fuse.4 b/man4/fuse.4
new file mode 100644
index 0000000..06d6f3f
--- /dev/null
+++ b/man4/fuse.4
@@ -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.
--
2.8.1
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next reply other threads:[~2016-12-10 7:20 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-10 7:20 Keno Fischer [this message]
[not found] ` <20161210072018.GA5267-9DCaDmOhoh+8M3too/+dENBPR1lH4CV8@public.gmane.org>
2016-12-10 14:17 ` [PATCH] fuse.4: Add new file describing /dev/fuse Michael Kerrisk (man-pages)
[not found] ` <96577e95-953c-994c-1dbb-2b4c92c1d2c4-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-12-10 21:03 ` Keno Fischer
[not found] ` <CABV8kRxw+Dps3iMi8GJOUiegUdxFBuaMF-icy=z0=faKUNi4SA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-12-11 9:27 ` Michael Kerrisk (man-pages)
2016-12-10 21:13 ` Nikolaus Rath
[not found] ` <87vaurbi7q.fsf-sKB8Sp2ER+yL2G7IJ6k9tw@public.gmane.org>
2016-12-10 21:19 ` Keno Fischer
2016-12-11 9:28 ` Michael Kerrisk (man-pages)
[not found] ` <1557a45c-8282-d181-1533-0204895ddc9b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-12-11 15:31 ` Nikolaus Rath
2016-12-11 18:16 ` Michael Kerrisk (man-pages)
[not found] ` <cd39e8cf-d59b-d485-2a01-85751a298bb5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-12-11 19:55 ` Nikolaus Rath
2016-12-12 6:21 ` Michael Kerrisk (man-pages)
2016-12-13 17:49 ` Nikolaus Rath
2016-12-14 7:25 ` Michael Kerrisk (man-pages)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161210072018.GA5267@juliacomputing.com \
--to=keno-9dcadmohoh+8m3too/+denbpr1lh4cv8@public.gmane.org \
--cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org \
--cc=mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=nikolaus-BTH8mxji4b0@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).