
存储驱动开发【免费下载链接】winfspWindows File System Proxy - FUSE for Windows项目地址https://gitcode.com/gh_mirrors/wi/winfsp点击查看免费下载本文以 WinFsp 仓库中的 memfs-fuse3 示例 为主线深入讲解一个基于 FUSE3 API 的纯内存文件系统in-memory FUSE3 file system从零构建与运行的完整路径并对照其源码剖析回调表、数据结构与内存管理的实现细节。读完本文你将掌握在 Windows 上通过 Visual Studio、Cygwin GCC 直链 WinFsp DLL、以及链接 CYGFUSE3 三种方式编译 FUSE3 文件系统的方法也能理解一个最小可用 FUSE 文件系统应有的内部骨架。一、memfs-fuse3 是什么memfs-fuse3是 WinFsp 官方提供的 FUSE3 示例程序位于 tst/memfs-fuse3/ 目录与 FUSE2 版本 tst/memfs-fuse/ 形成对照。它是一个纯内存文件系统所有文件、目录、符号链接、扩展属性xattr都保存在进程堆内存中不依赖任何磁盘存储进程退出后数据即消失。它的价值在于作为 WinFsp FUSE3 兼容层inc/fuse3/ 下的winfsp_fuse.h、fuse.h、fuse_common.h等头文件的最小可运行验证程序作为开发者编写自己 FUSE3 文件系统时的参考模板从fuse_operations回调注册、路径查找到fuse_main的启动流程一应俱全同时支持跨平台语义同一份 memfs-fuse3.cpp 源码既能构建为 Windows 原生程序也能在 Cygwin 环境下直接编译运行。该示例由三组文件构成文件作用memfs-fuse3.cpp文件系统核心实现约 620 行 C17MakefileCygwin GCC 两种链接方式的构建入口memfs-fuse3.sln / memfs-fuse3.vcxprojVisual Studio 解决方案与工程文件compat.h跨平台类型与宏适配层二、三种构建方式详解原文档明确指出 memfs-fuse3 可以使用以下工具构建下面逐一展开。2.1 使用 Visual Studio 构建memfs-fuse3.sln在 Windows 上直接用 Visual Studio 打开 memfs-fuse3.sln 即可构建。从 memfs-fuse3.vcxproj 可以梳理出工程的关键配置支持平台Debug/Release×Win32x86/x64/ARM64共 6 种组合其中 ARM64 平台下生成的目标文件名带-a64后缀如memfs-fuse3-a64.exe头文件路径AdditionalIncludeDirectories指向$(MSBuildProgramFiles32)\WinFsp\inc\fuse3与$(MSBuildProgramFiles32)\WinFsp\inc——这说明构建前需要先安装 WinFsp其 SDK 头文件与导入库默认位于Program Files (x86)\WinFsp\inc、WinFsp\lib下链接库Debug/Release的 x86/x64 平台链接winfsp-$(PlatformTarget).lib即winfsp-x86.lib/winfsp-x64.libARM64 平台链接 fsext 目录中的winfsp-a64.lib延迟加载通过DelayLoadDLLs指定winfsp-$(PlatformTarget).dll即 DLL 在fuse_main运行时才被加载程序启动更轻快其他Unicode字符集、Level3警告级别、禁用警告 4018有符号/无符号比较Debug 使用MultiThreadedDebug运行时、Release 使用MultiThreaded并开启WholeProgramOptimization。构建产物为控制台程序memfs-fuse3-platform.exe可通过命令行参数挂载内存盘并交互详见第五节。2.2 使用 Cygwin GCC 并直接链接 WinFsp DLLmake winfsp-fuse3这是 Cygwin 环境下的标准构建路径对应 Makefile 中的winfsp-fuse3目标memfs-winfsp-fuse3: export PKG_CONFIG_PATH$(PWD)/winfsp.install/lib memfs-winfsp-fuse3: memfs-fuse3.cpp ln -nsf regtool --wow32 get /HKLM/Software/WinFsp/InstallDir | cygpath -au -f - winfsp.install g $^ -o $ -g -Wall -stdgnu17 pkg-config fuse3 --cflags --libs执行make winfsp-fuse3时Makefile 会依次完成用regtool --wow32 get /HKLM/Software/WinFsp/InstallDir从注册表读取 WinFsp 的安装目录注意--wow32表示读取 32 位视角的注册表键通过cygpath -au -f -把 Windows 路径转换为 Cygwin 的 POSIX 路径ln -nsf在当前目录创建指向该安装目录的符号链接winfsp.install设置PKG_CONFIG_PATH指向winfsp.install/lib使pkg-config fuse3能解析到 WinFsp 随包提供的fuse3.pc与导入库调用g以-stdgnu17、-Wall、-g编译并展开pkg-config fuse3 --cflags --libs的头文件与链接参数。最终产物是可执行文件memfs-winfsp-fuse3。这种方式的本质是程序直接链接 WinFsp 自带的 FUSE3 兼容库winfsp-fuse3 DLL与 Visual Studio 方式殊途同归只是把工具链换成了 Cygwin GCC。2.3 使用 Cygwin GCC 并链接 CYGFUSE3make cygfuse3对应 Makefile 中的cygfuse3目标memfs-cygfuse3: memfs-fuse3.cpp g $^ -o $ -g -Wall -stdgnu17 pkg-config fuse3 --cflags --libs这里的fuse3来自 Cygwin 的CYGFUSE3 软件包其源码位于 opt/cygfuse/fuse3/包含cygfuse.c、fuse3.cygport、fuse3.pc.in等通过pkg-config自动获取 CYGFUSE3 的头文件与链接参数。与 2.2 的区别在于链接目标不同一个是 WinFsp 的 FUSE3 实现一个是 Cygwin 社区维护的 FUSE3 移植层。两种 Cygwin 方式共用同一份源码这正是 compat.h 存在的意义——它把 FUSE 类型fuse_stat、fuse_off_t、fuse_timespec等在非 Windows 平台下映射到系统原生类型stat、off_t、timespec并补齐S_IFMT、S_IFDIR等 POSIX 常量与XATTR_CREATE/XATTR_REPLACE标志保证源码在 Linux/macOS/Cygwin/Windows 上都能编译。三、源码实现原理3.1 从fuse_operations回调表看文件系统能力memfs-fuse3.cpp 通过一张静态fuse_operations回调表描述整个文件系统的行为这也是 FUSE 编程模型的精髓——文件系统 回调表 私有数据static fuse_operations ops { getattr, readlink, mknod, mkdir, unlink, rmdir, symlink, rename, link, chmod, chown, truncate, open, read, write, statfs, flush, release, 0, // fsync setxattr, getxattr, listxattr, removexattr, opendir, readdir, releasedir, 0, // fsyncdir init, 0, // destroy 0, // access 0, // create 0, // lock utimens, 0, // bmap };可以看到该示例实现了目录与文件操作mkdir/mknod/unlink/rmdir/rename、符号链接与硬链接symlink/link/readlink、权限与时间chmod/chown/utimens/truncate、读写open/read/write/flush/release、目录遍历opendir/readdir/releasedir、扩展属性setxattr/getxattr/listxattr/removexattr以及statfs/init而fsync、fsyncdir、destroy、access、create、lock、bmap均置为nullptr未实现ioctl则被#if 0注释掉——未实现的回调返回ENOSYS即可这正是 FUSE 允许部分实现、按需填充的特性。init回调里还做了能力协商conn-want | (conn-capable FUSE_CAP_READDIRPLUS)memfs-fuse3.cpp主动启用FUSE_CAP_READDIRPLUS定义于 inc/fuse3/fuse_common.h让readdir能携带每个条目的属性信息减少后续getattr调用。3.2 核心数据结构一棵由 node 组成的目录树所有数据保存在三个成员中memfs-fuse3.cppstd::mutex _mutex; // 全局互斥锁保护所有操作 fuse_ino_t _ino; // inode 号分配器从 1 递增 std::shared_ptrnode_t _root; // 根节点S_IFDIR | 00777每个node_t节点memfs-fuse3.cpp包含struct fuse_stat stat文件属性inode、模式、链接数、uid/gid、时间戳std::vectoruint8_t data文件内容对目录则是符号链接目标字符串std::unordered_mapstd::string, std::shared_ptrnode_t childmap子节点哈希表构成目录树std::unordered_mapstd::string, std::vectoruint8_t xattrmap扩展属性表。整个文件系统因此是一棵以_root为根的内存目录树路径解析由lookup_nodememfs-fuse3.cpp完成——按/分段逐级在childmap中查找。make_node创建节点时通过fuse_get_context()取得调用者的uid/gid赋给新节点memfs-fuse3.cpp体现 FUSE 的“上下文”机制。值得注意的工程细节64KB 分块预分配node_t::resizememfs-fuse3.cpp以64 * 1024字节为单元向上取整reserve容量避免频繁写入时反复扩容缩小容量时resizeshrink_to_fit释放多余内存打开即引用计数open_nodememfs-fuse3.cpp把fi-fh编码为shared_ptr的原始指针从而“即便文件被 unlink已打开的句柄仍能通过引用计数存活”——这是 FUSE 文件句柄使用的经典技巧close_node中delete该指针即归还引用目录循环防护rename中若目标为空名newname.empty()会返回-EINVAL防止把目录移入自身造成循环memfs-fuse3.cppxattr 标志语义setxattr依据XATTR_CREATE/XATTR_REPLACE分别返回-EEXIST/-ENOATTR并显式拒绝com.apple.ResourceFork属性返回-ENOTSUP以兼容 Apple 生态语义memfs-fuse3.cpp时间戳统一由now()生成基于std::chrono取秒与纳秒构造 FUSE 的fuse_timespecmemfs-fuse3.cpp。3.3 目录遍历与 READDIRPLUSreaddirmemfs-fuse3.cpp先填充.与..再遍历childmap逐个调用filler回调filler(buf, ., node-stat, 0, FUSE_FILL_DIR_PLUS); filler(buf, .., nullptr, 0, FUSE_FILL_DIR_PLUS); for (auto elem : node-childmap) if (0 ! filler(buf, elem.first.c_str(), elem.second-stat, 0, FUSE_FILL_DIR_PLUS)) break;每个条目都附带其stat并标记FUSE_FILL_DIR_PLUS定义于 inc/fuse3/fuse.h配合 3.1 中init开启的FUSE_CAP_READDIRPLUS目录列举时即批量携带属性是性能优化与 FUSE3 特性的示范。四、Windows 下的兼容适配compat.h 的作用Ccompat.h 是让同一份源码同时面向“Windows WinFsp”与“POSIX 系统 FUSE”的关键Windows 路径当定义了_WIN32且启用FSP_FUSE_SYM时把fuse_main重定义为(FspLoad(0), fuse_main_real(argc, argv, ops, sizeof *(ops), data))——即先调用 WinFsp 的FspLoad加载运行时再调用fuse_main_real并显式传入回调表大小用于 ABI 版本校验。这正是 inc/fuse3/winfsp_fuse.h 中fuse3_main_real与fuse_main_real别名的对应关系POSIX 路径把fuse_stat/fuse_off_t/fuse_timespec等一律 typedef 回系统类型补齐缺失的S_IF*常量、ENOATTR/ENODATA互映射并按平台选择sys/xattr.h或本地XATTR_CREATE/XATTR_REPLACE定义。这也解释了为什么同一个 Makefile 只需要切换pkg-config fuse3的来源就能生成链接 WinFsp-FUSE3 或 CYGFUSE3 两个不同目标。五、构建产物与运行方式Visual Studio 构建产物输出到解决方案的build\Configuration\目录目标名为memfs-fuse3-x86|x64|a64.exe由 vcxproj 的TargetName决定。Cygwin 构建分别生成memfs-winfsp-fuse3与memfs-cygfuse3两个可执行文件运行前请确认pkg-config fuse3能解析到对应.pc文件winfsp.install/lib或 Cygwin 的fuse3包。作为命令行 FUSE 程序运行时可通过 FUSE 标准参数指定挂载点与选项fuse_main的标准-f、-o等在挂载盘符上执行mkdir/echo file/cat file等操作即可验证内存文件系统的读写。由于数据仅存在于进程内存中进程退出后盘符消失、数据随之释放——这正是“内存文件系统”的直观体现。六、延伸阅读FUSE2 对照版本tst/memfs-fuse/README.md构建目标为make winfsp-fuse/make cygfuseFUSE3 头文件定义inc/fuse3/fuse.h、inc/fuse3/fuse_common.h、inc/fuse3/winfsp_fuse.hCYGFUSE3 移植实现opt/cygfuse/fuse3/更多文件系统示例tst/目录下还有 memfs原生 WinFsp API、passthrough-fuse3、ntptfs 等可与 memfs-fuse3 对照学习。赞分享存储驱动开发【免费下载链接】winfspWindows File System Proxy - FUSE for Windows项目地址https://gitcode.com/gh_mirrors/wi/winfsp点击查看免费下载相关推荐WinFsp 的 Passthrough-FUSE3 文件系统源码实现与三种构建方式深度解析WinFsp 的 Passthrough FUSE3 文件系统源码实现与三种构建方式深度解析 导读 本文以 WinFsp 仓库中的 tst/passthro存储驱动开发WinFsp 实战用 memfs-fuse 构建一个可移植的内存 FUSE 文件系统WinFsp 实战用 memfs fuse 构建一个可移植的内存 FUSE 文件系统 在 Windows 上开发 FUSE 文件系统通常要面对工具链与类型系存储驱动开发终极指南如何快速掌握memfs内存文件系统实现终极指南如何快速掌握memfs内存文件系统实现 memfs 是一个强大的JavaScript内存文件系统工具库为Node.js和浏览器环境提供完整的文件系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考