From 5963519cfeba16cfdb4868e470e820901807ad69 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 10 Dec 2016 02:20:18 -0500 Subject: [PATCH] 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 --- 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 000000000..06d6f3fe2 --- /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 +.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.