NFSv4是一种有状态的协议,客户端需要记录用户操作的各种状态。当用户打开文件时客户端需要记住各个文件的状态。不考虑文件锁的情况下,跟文件状态相关的两个数据结构是nfs4_state_owner和nfs4_state。nfs4_state_owner表示客户端一个用户,包含了这个用户打开的所有文件,而nfs4_state表示用户打开的一个文件,这几个数据结构之间的关系如下图所示。
上面这个例子中,客户端包含了两个用户:alice和bob,每个用户用一个nfs4_state_owner表示。alice打开了两个文件:file1和file2,每个文件用一个nfs4_state表示。nfs_server中与nfs4_state_owner相关的字段如下:
struct nfs_server {
// 这是一个lru链表,链接了这个nfs_server中使用完毕的nfs4_state_owner结构.
struct list_head state_owners_lru;
// 这是一棵红黑树,链接了这个nfs_server中所有的nfs4_state_owner结构.
struct rb_node so_server_node;
// 每个nfs4_state_owner结构需要一个编号,openowner_id生成编号.
struct ida openowner_id;
}
nfs4_state_owner结构的定义如下:
struct nfs4_state_owner {
struct nfs_server *so_server; // 这个结构所属于的nfs_server结构
// 将nfs4_state_owner空闲下来,就将它挂载到nfs_server->state_owners_lru中.
// 注意:即使挂载到lru链表中了,也没有从红黑树中删除.
struct list_head so_lru;
// 这里保存的是过期时间,也就是将这个nfs4_state_owner挂载到nfs_server->state_owners_lru中的时间
unsigned long so_expires;
// nfs_server结构中所有的nfs4_state_owner结构构成了一棵红黑树,
// so_server_node负责将这个nfs4_state_owner结构添加到红黑树中.
struct rb_node so_server_node;
// 这里保存的是用户信息
struct rpc_cred *so_cred; /* Associated cred */
spinlock_t so_lock; // 保护这个结构的一个自旋锁
atomic_t so_count; // 这个数据结构的引用计数
// 这是一些标志位,目前只定义了两个标志位:NFS_OWNER_RECLAIM_REBOOT,NFS_OWNER_RECLAIM_NOGRACE
unsigned long so_flags;
// 这个一个链表头,保存的数据结构是nfs4_state,每个nfs4_st