FUSE - Linux手册页

时间:2019-08-20 18:01:45  来源:igfitidea点击:

Linux程序员手册 第4部分
更新日期: 2018-02-02

名称

fuse-用户空间(FUSE)设备中的文件系统

语法

#include <linux/fuse.h>

说明

该设备是FUSE文件系统驱动程序和希望提供文件系统的用户空间进程之间的主要接口(在本手册的其余部分称为文件系统守护程序)。本手册页供有兴趣了解内核接口本身的人员使用。那些实现FUSE文件系统的用户可能希望利用用户空间库(例如libfuse)来抽象出低级接口。

FUSE的核心是一个简单的客户端-服务器协议,其中Linux内核是客户端,守护程序是服务器。在获得该设备的文件描述符之后,守护程序可以读取(2)来自该文件描述符的请求,并期望将其回复写回(2)。重要的是要注意,文件描述符与唯一的FUSE文件系统相关联。特别是,打开此设备的第二个副本将不允许访问通过第一个文件描述符创建的资源(反之亦然)。

The basic protocol

守护程序读取的每条消息均以以下结构所描述的标头开头:

struct fuse_in_header {
    uint32_t len;       /* Total length of the data,
                           including this header */
    uint32_t opcode;    /* The kind of operation (see below) */
    uint64_t unique;    /* A unique identifier for this request */
    uint64_t nodeid;    /* ID of the filesystem object
                           being operated on */
    uint32_t uid;       /* UID of the requesting process */
    uint32_t gid;       /* GID of the requesting process */
    uint32_t pid;       /* PID of the requesting process */
    uint32_t padding;
};

头之后是特定于所请求操作的可变长度数据部分(可能为空)(所请求的操作由操作码指示)。

然后,守护程序应处理该请求,并在适用的情况下,通过对文件描述符执行write(2)来发送答复(几乎所有操作都需要答复;如果没有,则在下面进行记录)。所有答复必须以以下标头开头:

struct fuse_out_header {
    uint32_t len;       /* Total length of data written to
                           the file descriptor */
    int32_t  error;     /* Any error that occurred (0 if none) */
    uint64_t unique;    /* The value from the
                           corresponding request */
};

根据执行的请求,此标头后还跟随着(可能为空)可变大小的数据。但是,如果答复是错误答复(即设置了错误),则不应再发送独立于请求的其他有效负载数据。

Exchanged messages

本部分应包含协议中每个消息的文档。该手册页当前不完整,因此未记录所有消息。对于每条消息,首先给出内核发送的结构,然后是消息语义的描述。

FUSE_INIT
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 */
};
这是内核向守护程序发送的第一个请求。它用于协商协议版本和其他文件系统参数。请注意,协议版本可能会影响协议中任何结构的布局(包括该结构)。因此,守护程序必须记住每个会话的协商版本和标志。在撰写此手册页时,支持的最高内核协议版本为7.26。
用户应注意,对于较早或较新的协议版本,本手册页中的描述可能不完整或不正确。
此请求的回复具有以下格式:
struct fuse_init_out {
    uint32_t major;
    uint32_t minor;
    uint32_t max_readahead;   /* Since v7.6 */
    uint32_t flags;           /* Since v7.6; some flags bits
                                 were introduced later */
    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];
};
如果内核支持的主要版本大于守护程序支持的主要版本,则答复应仅包含uint32_t major(遵循通常的标头),指示守护程序支持的最大主要版本。然后,内核将发出一个符合旧版本的新FUSE_INIT请求。在相反的情况下,守护程序应该悄悄地退回到内核的主要版本。
协商的次要版本被认为是守护程序和内核提供的次要版本的最小值,并且双方都应使用与所述次要版本相对应的协议。
FUSE_GETATTR
struct fuse_getattr_in {
    uint32_t getattr_flags;
    uint32_t dummy;
    uint64_t fh;      /* Set only if
                         (getattr_flags & FUSE_GETATTR_FH)
};
请求的操作是计算要由stat(2)返回的属性以及给定文件系统对象的类似操作。要为其计算属性的对象由header->nodeid指示,或者,如果设置了FUSE_GETATTR_FH标志,则由文件句柄fh指示。后一种操作情况类似于fstat(2)。
出于性能原因,可以将这些属性在内核中缓存指定的时间。在没有超过缓存超时的情况下,将从缓存中提供属性,并且不会引起其他FUSE_GETATTR请求。
然后,应以以下结构返回计算出的属性和请求的缓存超时:
struct fuse_attr_out {
    /* Attribute cache duration (seconds + nanoseconds) */
    uint64_t attr_valid;
    uint32_t attr_valid_nsec;
    uint32_t dummy;
    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;
    } attr;
};
FUSE_ACCESS
struct fuse_access_in {
    uint32_t mask;
    uint32_t padding;
};
如果未使用default_permissions挂载选项,则此请求可用于权限检查。没有预期的答复数据,但是可以通过在答复标头中设置错误字段来照常指示错误(特别是,可以通过返回-EACCES指示访问被拒绝的错误)。
FUSE_OPENand FUSE_OPENDIR
struct fuse_open_in {
    uint32_t flags;     /* The flags that were passed
                           to the open(2) */
    uint32_t unused;
};
请求的操作是打开由header->nodeid指示的节点。这意味着什么的确切语义将取决于所实现的文件系统。但是,至少文件系统应验证请求的标志对于指示的资源是否有效,然后以以下格式发送答复:
struct fuse_open_out {
    uint64_t fh;
    uint32_t open_flags;
    uint32_t padding;
};
The fh

field is an opaque identifier that the kernel will use to refer
to this resource
The
open_flags

field is a bit mask of any number of the flags
that indicate properties of this file handle to the kernel:

FOPEN_DIRECT_IO
绕过此打开文件的页面缓存。
FOPEN_KEEP_CACHE
打开时不要使数据缓存无效。
FOPEN_NONSEEKABLE
该文件不可搜索。
FUSE_READand FUSE_READDIR
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;
};
所请求的操作是从offset开始读取文件或目录的最大字节大小。字节应直接在通常的答复标头之后返回。
FUSE_INTERRUPT
struct fuse_interrupt_in {
    uint64_t unique;
};
请求的操作是取消由unique指示的挂起操作。该请求无需回复。但是,收到此消息本身并不会取消所指示的操作。内核仍将期望对所述操作的答复(例如,EINTR错误或短读)。对于给定的操作,最多将发出一个FUSE_INTERRUPT请求。发出上述操作后,内核将不间断地等待指示请求的完成。
FUSE_LOOKUP
标头后紧跟的是要在标头->nodeid指示的目录中查找的文件名。预期的答复形式为:
struct fuse_entry_out {
    uint64_t nodeid;            /* Inode ID */
    uint64_t generation;        /* Inode generation */
    uint64_t entry_valid;
    uint64_t attr_valid;
    uint32_t entry_valid_nsec;
    uint32_t attr_valid_nsec;
    struct fuse_attr attr;
};
在文件系统的生存期内,nodeid和生成的组合必须是唯一的。
超时和属性的解释与FUSE_GETATTR相同。
FUSE_FLUSH
struct fuse_flush_in {
    uint64_t fh;
    uint32_t unused;
    uint32_t padding;
    uint64_t lock_owner;
};
请求的操作是清除对指示的文件句柄的所有未决更改。预计没有回复数据。但是,一旦刷新操作完成,仍然需要发出一个空的答复消息。
FUSE_RELEASEand FUSE_RELEASEDIR
struct fuse_release_in {
    uint64_t fh;
    uint32_t flags;
    uint32_t release_flags;
    uint64_t lock_owner;
};
它们分别与FUSE_OPEN和FUSE_OPENDIR相反。守护程序现在可以释放与文件句柄fh相关的任何资源,因为内核将不再引用它。没有与此请求相关联的答复数据,但是一旦请求已被完全处理,仍然需要发出答复。
FUSE_STATFS
此操作为此文件系统实现statfs(2)。没有与此请求关联的输入数据。预期的答复数据具有以下结构:
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;
};
有关这些字段的解释,请参见statfs(2)。

错误说明

E2BIG
当内核的请求对于提供的缓冲区而言太大而请求是FUSE_SETXATTR时,从read(2)操作返回。
EINVAL
如果回复的验证失败,则从write(2)返回。验证不会捕获所有答复错误。但是,会检测到基本错误,例如简短答复或不正确的唯一值。
EIO
当内核的请求对于提供的缓冲区太大时,从read(2)操作返回。
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
EIO.

Among the possible incorrect uses are:

*
为先前已报告给内核的索引节点更改模式和S_IFMT;要么
*
对内核的答复比内核预期的要短。
ENODEV
如果已卸载FUSE文件系统,则从read(2)和write(2)返回。
EPERM
从尚未安装的/ dev / fuse文件描述符的操作返回。

遵循规范

FUSE文件系统特定于Linux。

备注

本手册页面中尚未记录以下消息:

FUSE_BATCH_FORGET
FUSE_BMAP
FUSE_CREATE
FUSE_DESTROY
FUSE_FALLOCATE
FUSE_FORGET
FUSE_FSYNC
FUSE_FSYNCDIR
FUSE_GETLK
FUSE_GETXATTR
FUSE_IOCTL
FUSE_LINK
FUSE_LISTXATTR
FUSE_LSEEK
FUSE_MKDIR
FUSE_MKNOD
FUSE_NOTIFY_REPLY
FUSE_POLL
FUSE_READDIRPLUS
FUSE_READLINK
FUSE_REMOVEXATTR
FUSE_RENAME
FUSE_RENAME2
FUSE_RMDIR
FUSE_SETATTR
FUSE_SETLK
FUSE_SETLKW
FUSE_SYMLINK
FUSE_UNLINK
FUSE_WRITE

另外参见

fusermount(1),mount.fuse(8)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/