注意
本文档适用于 Ceph 的开发版本。
CephFS 中的功能
当客户端想要对一个 inode 进行操作时,它会通过各种方式查询 MDS,MDS 随后会授予客户端一组功能。这授予了客户端以各种方式对该 inode 进行操作的权限。与其他网络文件系统(例如 NFS 或 SMB)的一个主要区别是,授予的功能非常细粒度,并且多个客户端可能在同一个 inode 上持有不同的功能。
功能类型
有几个“通用”功能位。它们表示该功能授予的能力类型。
/* generic cap bits */
#define CEPH_CAP_GSHARED 1 /* (metadata) client can read (s) */
#define CEPH_CAP_GEXCL 2 /* (metadata) client can read and update (x) */
#define CEPH_CAP_GCACHE 4 /* (file) client can cache reads (c) */
#define CEPH_CAP_GRD 8 /* (file) client can read (r) */
#define CEPH_CAP_GWR 16 /* (file) client can write (w) */
#define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes (b) */
#define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF (a) */
#define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io (l) */
然后将这些位按特定位数进行移位。这些移位表示 inode 数据或元数据的一部分,该功能正在其上被授予。
/* per-lock shift */
#define CEPH_CAP_SAUTH 2 /* A */
#define CEPH_CAP_SLINK 4 /* L */
#define CEPH_CAP_SXATTR 6 /* X */
#define CEPH_CAP_SFILE 8 /* F */
然而,只有某些通用功能类型会被授予某些“移位”。特别是,只有 FILE 移位才会有超过前两个位。
| AUTH | LINK | XATTR | FILE
2 4 6 8
从上面我们可以得到一些常量,这些常量是通过取每个位值并将其移位到字中的正确位置生成的。
#define CEPH_CAP_AUTH_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SAUTH)
然后可以将这些位进行或运算,以生成表示一组功能的位掩码。
有一个例外。
#define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */
“pin”只是将 inode 锁定在内存中,不授予任何其他功能。
图示
+---+---+---+---+---+---+---+---+
| p | _ |As x |Ls x |Xs x |
+---+---+---+---+---+---+---+---+
|Fs x c r w b a l |
+---+---+---+---+---+---+---+---+
第二个位目前未使用。
每个功能授予的权限
虽然这是授予(和通信)功能的方式,但重要的是它们实际允许客户端做什么。
PIN: 这只是将 inode 锁定在内存中。这足以让客户端获取 inode 号,以及设备 inode 中的主要或次要号等其他不可变内容,或符号链接内容。
AUTH: 这授予了访问与身份验证相关的元数据的能力。特别是所有者、组和模式。请注意,进行完整的权限检查可能还需要访问 ACL,这些 ACL 存储在 xattrs 中。
LINK: inode 的链接计数。
XATTR: 访问或操作 xattrs 的能力。请注意,由于 ACL 存储在 xattrs 中,因此在检查权限时有时也需要访问它们。
FILE: 这是最重要的功能。它允许客户端访问和操作文件数据。它还涵盖了与文件数据相关的某些元数据——特别是大小、mtime、atime 和 ctime。
简写
请注意,客户端日志也可以提供功能的紧凑表示。例如
pAsLsXsFs
“p”代表 pin。每个大写字母对应于移位值,每个移位后的小写字母对应于在每个移位中授予的实际功能。
锁状态与功能之间的关系
在 MDS 中,每个 inode 有四个不同的锁:simplelock、scatterlock、filelock 和 locallock。每个锁有几种不同的锁状态,MDS 将根据锁状态向客户端颁发功能。
在每个状态下,MDS Locker 都会尝试向允许的客户端颁发所有功能,即使某些功能不是客户端需要或想要的,因为预先颁发功能可以在某些情况下减少延迟。
如果只有一个客户端,它通常是所有 inode 的 loner 客户端。在多个客户端的情况下,MDS 将尝试根据客户端需要或想要的功能为每个 inode 计算出一个 loner 客户端,但这通常会失败。loner 客户端将始终获得所有功能。
filelock 将控制文件的部分元数据和文件内容的访问权限。元数据包括 mtime、atime、size 等。
Fs: 一旦一个客户端拥有它,所有其他客户端都将被拒绝 Fw。
Fx: 只有 loner 客户端被允许此功能。一旦锁状态转换为 LOCK_EXCL,loner 客户端将被授予此功能以及所有其他文件功能,除了 Fl。
Fr: 一旦一个客户端拥有它,Fb 功能将已经从所有其他客户端撤销。
如果客户端只请求读取文件,锁状态将直接转换为 LOCK_SYNC 稳定状态。所有客户端都可以从 auth MDS 获得 Fscrl 功能,并从 replica MDSes 获得 Fscr 功能。
如果多个客户端对同一个文件进行读写,那么锁状态最终将转换为 LOCK_MIX 稳定状态,所有客户端都可以从 auth MDS 获得 Frwl 功能,并从 replica MDSes 获得 Fr。Fcb 功能不会授予所有客户端,客户端将进行同步读写。
Fw: 如果没有 loner 客户端,一旦一个客户端拥有此功能,Fsxcb 功能将不会授予其他客户端。
如果多个客户端对同一个文件进行读写,那么锁状态最终将转换为 LOCK_MIX 稳定状态,所有客户端都可以从 auth MDS 获得 Frwl 功能,并从 replica MDSes 获得 Fr。Fcb 功能不会授予所有客户端,客户端将进行同步读写。
Fc: 此功能意味着客户端可以缓存文件读取,应与 Fr 功能一起颁发,并且只有在这种使用情况下才有意义。
虽然实际上在某些稳定或过渡状态下,即使未授予 Fr 功能,它们也倾向于保持 Fc 允许,因为这可以避免强制客户端删除完整缓存,例如在简单的文件大小扩展或截断使用情况下。
Fb: 此功能意味着客户端可以缓冲文件写入,应与 Fw 功能一起颁发,并且只有在这种使用情况下才有意义。
虽然实际上在某些稳定或过渡状态下,即使未授予 Fw 功能,它们也倾向于保持 Fc 允许,因为这可以避免强制客户端删除脏缓冲区,例如在简单的文件大小扩展或截断使用情况下。
Fl: 此功能意味着客户端可以执行惰性 IO。LazyIO 放松了 POSIX 语义。即使文件被多个客户端上的多个应用程序打开,也允许缓冲读写。应用程序负责自行管理缓存一致性。