土法炼钢兴趣小组的算法知识备份

【操作系统百科】FUSE

文章导航

分类入口
os
标签入口
#fuse#user-filesystem#virtio-fs#passthrough#io-uring

目录

在用户态实现文件系统——SSHFS、GlusterFS、CephFS FUSE client、rclone mount 都用 FUSE。代价是每次 I/O 多两次上下文切换。如何逼近内核文件系统性能?

一、先看图

sequenceDiagram
    participant App as 用户进程
    participant VFS as VFS
    participant FUSE_K as FUSE 内核模块
    participant FUSE_D as FUSE daemon<br/>(用户态 FS)

    App->>VFS: read("/mnt/fuse/file")
    VFS->>FUSE_K: fuse_file_read_iter()
    FUSE_K->>FUSE_D: /dev/fuse → FUSE_READ 请求
    FUSE_D->>FUSE_D: 处理(网络/本地)
    FUSE_D->>FUSE_K: /dev/fuse → 写回数据
    FUSE_K->>VFS: 返回数据
    VFS->>App: read() 完成

二、FUSE 架构

2.1 三部分

2.2 协议

FUSE 请求/响应是结构化消息:

struct fuse_in_header {
    uint32_t len;
    uint32_t opcode;   // FUSE_READ, FUSE_WRITE, FUSE_LOOKUP...
    uint64_t unique;   // 请求 ID
    uint64_t nodeid;   // inode 编号
    uint32_t uid, gid, pid;
};

大约 50 种 opcode 覆盖所有 VFS 操作。

三、性能瓶颈

每次 I/O:

  1. 用户进程 → 内核(syscall)
  2. 内核 → FUSE daemon(context switch + copy)
  3. FUSE daemon 处理
  4. FUSE daemon → 内核(write /dev/fuse)
  5. 内核 → 用户进程

两次额外上下文切换 + 两次数据拷贝

3.1 benchmark 数据

典型场景(4KB 随机读):

吞吐下降 30%-70%。

四、优化手段

4.1 writeback cache

mount.fuse3 myfs /mnt -o writeback_cache

启用页缓存的 writeback 模式 → 小写合并 → 减少到 daemon 的请求次数。

4.2 splice

FUSE 支持 splice 零拷贝传输:daemon 通过 splice 直接在 pipe buffer 和 /dev/fuse 之间移动数据。

4.3 multi-threaded daemon

libfuse 支持多线程处理请求。单线程 daemon 是性能反模式。

4.4 readahead

内核 FUSE 模块支持 readahead(max_readahead)→ 预读合并请求。

五、FUSE passthrough(6.9+)

FUSE_PASSTHROUGH:daemon 告诉内核”这个文件直接 I/O 到底层 fd”→ 后续读写完全在内核完成,不经过 daemon。

// daemon 在 FUSE_OPEN 响应里
out->passthrough.fd = backing_fd;
out->open_flags |= FOPEN_PASSTHROUGH;

效果:接近原生文件系统性能。元数据操作还走 daemon,但数据路径完全旁路。

用例:Android FUSE(用户态控制权限,数据走 passthrough)。

六、virtio-fs

虚拟机场景:guest 访问 host 文件。传统 9p → 性能差。

virtio-fs = FUSE 协议 + virtio 传输 + DAX(直接映射 host 页缓存到 guest)。

flowchart LR
    GUEST[Guest<br/>FUSE 内核模块] -->|virtio| VMM[virtiofsd<br/>Host daemon]
    VMM --> HOST_FS[Host 文件系统]
    GUEST -.->|DAX window| HOST_FS
    classDef guest fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef host fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class GUEST guest
    class VMM,HOST_FS host

DAX 模式:guest 直接 mmap host 页 → 零拷贝 + 共享页缓存

七、io_uring FUSE(实验性)

传统 FUSE 数据路径:read/write /dev/fuse → syscall 开销。

io_uring FUSE(LSFMM 2023 讨论):把 FUSE 请求/响应放到 SQ/CQ ring → 减少 syscall 和上下文切换。尚未合入主线。

八、常见 FUSE 文件系统

项目 用途
SSHFS SSH 远程挂载
rclone mount 云存储挂载
GlusterFS 分布式存储
CephFS FUSE Ceph 用户态客户端
NTFS-3G NTFS 读写
s3fs / goofys S3 挂载
juicefs 云原生文件系统

九、开发 FUSE 文件系统

// libfuse3 最小示例
static int myfs_getattr(const char *path, struct stat *stbuf,
                        struct fuse_file_info *fi) {
    if (strcmp(path, "/") == 0) {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
        return 0;
    }
    return -ENOENT;
}

static const struct fuse_operations myfs_ops = {
    .getattr = myfs_getattr,
};

int main(int argc, char *argv[]) {
    return fuse_main(argc, argv, &myfs_ops, NULL);
}

Go: bazil.org/fuse、Rust: fuser

十、小结


参考文献

工具


上一篇OverlayFS 下一篇VFS I/O 路径

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-18 · os

【操作系统百科】io_uring 内核内部

io_uring 用共享内存 ring buffer 实现零 syscall 异步 I/O——SQ/CQ、SQPOLL、IOPOLL、注册 fd/buffer、multishot、安全模型演化。本文深入内核实现与工程实践。

2026-05-23 · os

【操作系统百科】异步 I/O 模型 benchmark

epoll、io_uring、libaio、阻塞线程池——四种异步模型的真实性能对比。本文用统一 workload 量化 echo server、静态文件服务、数据库 I/O 场景下的吞吐、延迟与 CPU 开销。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。


By .