pnfs 中的引用计数¶
这里有几个相互关联的缓存。我们有布局可以引用多个设备,每个设备可以引用多个数据服务器。每个数据服务器可以被多个设备引用。每个设备可以被多个布局引用。为了保持所有这些的清晰,我们需要进行引用计数。
struct pnfs_layout_hdr¶
在线命令 LAYOUTGET 对应于 struct pnfs_layout_segment,通常用变量名 lseg 表示。每个 nfs_inode 可能会在 nfsi->layout 中保存指向这些布局段的缓存的指针,类型为 struct pnfs_layout_hdr。
我们在每个引用它的未完成的 RPC 调用(LAYOUTGET、LAYOUTRETURN、LAYOUTCOMMIT)中,以及其中包含的每个 lseg 中,都引用指向它的 inode 的头。
每个头(当非空时)也会被放在与 struct nfs_client (cl_layouts) 关联的列表上。放在此列表上不会增加引用计数,因为布局由将其保留在列表中的 lseg 保留。
deviceid_cache¶
lseg 引用设备 ID,这些 ID 会根据每个 nfs_client 和布局驱动程序类型进行解析。设备 ID 保存在 RCU 缓存中 (struct nfs4_deviceid_cache)。缓存本身在每次挂载时都会被引用。条目 (struct nfs4_deviceid) 本身在引用它们的每个 lseg 的生命周期内都会被保留。
使用 RCU 是因为 deviceid 基本上是一个写入一次,读取多次的数据结构。32 个桶的 hlist 大小需要更好的理由,但考虑到我们每个文件系统可以有多个 deviceid,并且每个 nfs_client 可以有多个文件系统,这似乎是合理的。
哈希代码是从 nfsd 代码库复制的。关于哈希和此算法的变体的讨论可以在这里找到。
数据服务器缓存¶
文件驱动程序设备引用数据服务器,这些数据服务器保存在模块级缓存中。它的引用在指向它的 deviceid 的生命周期内保持。
lseg¶
lseg 维护一个额外的引用,对应于将它保留在 pnfs_layout_hdr 列表中的 NFS_LSEG_VALID 位。当从 pnfs_layout_hdr 列表中删除最后一个 lseg 时,会设置 NFS_LAYOUT_DESTROYED 位,防止添加任何新的 lseg。
布局驱动程序¶
PNFS 利用所谓的布局驱动程序。STD 定义了 4 种基本布局类型:“files”、“objects”、“blocks” 和 “flexfiles”。对于这些类型中的每一种,都有一个布局驱动程序,其中有一个通用的函数向量表,nfs-client pnfs-core 调用该表来实现不同的布局类型。
Files-layout-driver 代码位于:fs/nfs/filelayout/.. 目录 Blocks-layout-driver 代码位于:fs/nfs/blocklayout/.. 目录 Flexfiles-layout-driver 代码位于:fs/nfs/flexfilelayout/.. 目录
blocks-layout 设置¶
TODO:记录块布局驱动程序的设置需求