不同应用访问数据的方式并不相同:有的依赖 POSIX 文件接口,有的基于 S3 API 构建,也有用户希望通过文件管理器浏览和编辑远程文件。JuiceFS 的多协议访问能力,正是为了让这些工具能够访问同一套文件系统。
本文会先说明 S3 Gateway 与 WebDAV 共享的初始化链路,再说明二者的适用场景和常见映射关系,最后分别展开二者的实现原理与边界。
01 共用一条初始化链路
JuiceFS 底层由元数据引擎和对象存储组成:元数据引擎管理目录、属性、锁、会话等信息,对象存储保存实际文件数据块。

从实现上看,S3 Gateway 和 WebDAV 会先经过同一条服务初始化链路。服务进程根据元数据地址、监听地址,以及 subdir、read-only、cache、limits、access-log、metrics 等公共参数创建 JuiceFS 客户端,依次初始化元数据客户端、对象存储、数据块缓存和 VFS 配置,最终得到 fs.FileSystem。

也就是说,二者的共同基础不是 FUSE 挂载点,而是一个带会话、缓存、指标和后台任务的原生 JuiceFS 客户端。S3 请求和 WebDAV 请求进入各自的协议适配层之前,已经共享同一个 JuiceFS FileSystem 和同一个文件系统命名空间。
02 适用场景与常见映射
共用初始化链路说明了二者如何接入同一个文件系统。实际使用时,更关键的是访问方式的选择:哪些场景适合 S3 Gateway,哪些场景适合 WebDAV,以及常见请求会如何映射到 JuiceFS 操作。
- Linux 应用、训练任务或需要完整文件系统语义的工作负载,优先使用 FUSE / CSI。
- 已基于 S3 SDK、AWS CLI、MinIO Client 或对象存储工具链构建的应用,优先使用 S3 Gateway。
- 桌面文件管理器访问、DAV/rclone 同步、Office/Apps 协作和简单共享,优先使用 WebDAV。


03 S3 Gateway 原理:对象语义到文件系统操作
S3 Gateway 负责把 S3 协议请求转换为 JuiceFS 文件系统操作。下文将从请求链路、内部状态、关键语义转换和权限协同四个层面展开。
请求链路:MinIO S3 Server 到 jfsObjects
MinIO S3 Server 负责 S3 协议层处理,包括请求路由、签名校验、认证授权和 Multipart Upload 编排等能力。请求通过协议层处理后,会进入 JuiceFS 实现的 ObjectLayer,也就是 jfsObjects。jfsObjects 负责把对象层面的读写、列举、删除和属性访问,转换为 JuiceFS 文件系统调用。

状态保存:内部命名空间如何承载 Gateway 状态
在请求转换过程中,Gateway 不只访问用户可见的 object path,也会使用内部命名空间保存服务自身需要的状态。例如,.sys/tmp 用于临时写入,.sys/uploads 用于 Multipart Upload 状态,.minio.sys 用于保存 MinIO/IAM 相关元数据。
这些内部路径不属于普通用户理解中的业务数据,但它们是 Gateway 维持上传过程、分片状态和权限配置所需的基础。
语义转换:PutObject、Multipart、Bucket 与 Metadata
S3 对象模型和文件系统模型并不完全一致,因此 Gateway 需要在几个关键位置做语义转换。
PutObject 需要保证对象上传完成后才对外可见。为避免客户端读到未完成对象,JuiceFS Gateway 会先写入临时文件,并保存 metadata/tag 等对象属性,完成后再通过 Rename 提交到目标路径。借助文件系统 Rename 的原子性,Gateway 可以把对象写入从"未提交"切换到"已提交"。

Multipart Upload 需要把多个 part 合并为最终对象。JuiceFS Gateway 可以利用 CopyFileRange 等文件系统能力组合已写入的 part,并通过 Rename 提交最终文件。这样主要调整的是文件系统元数据关系,而不是重新搬运全部数据。

Bucket 映射用于处理对象命名空间和文件路径之间的关系。单桶模式下,文件系统名称对应 bucket;多桶模式下,顶层目录映射为 bucket。对象的 metadata、tag、ETag 等属性,则通过文件扩展属性 xattr 保存。
权限协同:IAM 与多实例
S3 Gateway 还需要处理身份和权限信息,包括 root 用户、普通用户、policy、service account 等。这些配置会通过内部路径保存在 JuiceFS 文件系统中,从而在多个 Gateway 实例之间复用。
因此,多个 Gateway 实例可以共享同一套 IAM 配置;但每个实例会缓存 IAM 信息,权限变更并非瞬时同步,实际部署时需要考虑刷新周期。
04 WebDAV 原理:文件协议到 JuiceFS 操作
WebDAV 的起点与 S3 Gateway 不同。它面向文件访问场景,常见客户端包括 macOS Finder、DAV/rclone,以及部分 Office / Apps 客户端。由于 WebDAV 协议本身就包含文件、目录、属性等概念,它不需要像 S3 Gateway 那样先处理 bucket、object、key 与 path、file 之间的模型转换。
请求链路:从 HTTP 入口到 webdavFS
WebDAV 请求进入 JuiceFS 后,会先经过 net/http 与 indexHandler。这一层主要处理 HTTP 入口相关能力,例如认证、传输和目录访问请求的转换。
之后,请求进入 x/net/webdav.Handler,由它完成 WebDAV 协议层处理,并把协议方法转换为 webdavFS 可以处理的文件访问请求。

进入 webdavFS 后,Handler 传入的文件访问请求会被转换为打开、创建、读写、重命名、删除和属性设置等 JuiceFS 文件系统调用。由于 WebDAV 协议本身接近文件系统语义,这里的重点不是重建对象模型,而是处理请求方法、文件打开标志和属性状态如何落到 JuiceFS 操作上。
状态边界:dead properties 与 LOCK
WebDAV 的适配不只涉及数据读写,还涉及协议自身的状态。dead properties 可以用 JSON 形式保存到 xattr,从而落到 JuiceFS 的文件属性体系中;但 LOCK 状态不同,它当前保存在服务进程内存中。单实例部署通常没有问题;多实例部署时,不同实例无法自动同步锁状态。
这些限制通常不影响 Finder 浏览、简单共享或 DAV/rclone 同步;但如果业务强依赖 WebDAV 文件锁语义,需要在部署方式和客户端行为上单独验证。
S3 Gateway 和 WebDAV 共享同一条 JuiceFS 客户端初始化链路,并访问同一个文件系统命名空间;差异在于,S3 Gateway 需要将对象语义转换为文件系统操作,而 WebDAV 更接近文件访问语义。因此,访问方式的选择最终应回到应用本身:它是按对象组织数据,还是按文件和目录操作数据。
我们希望本文中的一些实践经验,能为正在面临类似问题的开发者提供参考,如果有其他疑问欢迎加入 JuiceFS 社区与大家共同交流。