OPEN操作中的数据结构
来源:互联网 发布:网络推广部人员架构 编辑:程序博客网 时间:2024/06/05 03:29
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_state结构表示用户打开的一个文件. struct list_head so_states; struct nfs_seqid_counter so_seqid; // 这是一个nfs_seqid_counter结构,看下面.};nfs4_state_owner结构最后一个字段是nfs_seqid_counter结构,这个数据结构保证了OPEN操作的序列化,这个数据结构定义如下:
struct nfs_seqid_counter { ktime_t create_time; // 这是nfs4_state_owner结构的创建时间 // onwer_id表示一个编号,可以唯一标识一个nfs4_state_owner结构 int owner_id; int flags; // 一些标志位 // 这个计数初始化为0,每执行一次OPEN/OPEN_DOWNGRADE/LOCK/CLOSE操作,这个计数加1. // 依靠这个字段实现操作的序列化. u32 counter; // 保护nfs4_state_owner结构的一个自旋锁结构. spinlock_t lock; /* Protects the list */ // 这里包含了很多nfs_seqid结构,构成了一个链表. // 每个nfs_seqid关联了一个RPC任务,实现RPC请求的序列化. // 当RPC任务执行完毕后,从链表中删除相应的nfs_seqid结构. struct list_head list; /* Defines sequence of RPC calls */ // RPC等待队列 struct rpc_wait_queue wait; /* RPC call delay queue */};NFSv4中的操作必须实现序列化,因此每个RPC任务关联到一个nfs_seqid结构中,这些nfs_seqid链接到一个链表上,前一个任务执行完毕后才能执行下一个任务。nfs_seqid结构的定义如下:
// 一个nfs_seqid_counter包含多个nfs_seqid 只是在执行RPC任务期间才使用这个结构,执行完后马上删除.struct nfs_seqid { struct nfs_seqid_counter *sequence; // 这个nfs_seqid所属于的nfs_seqid_counter结构 struct list_head list; // 链接到nfs_seqid_counter结构中 struct rpc_task *task; // 这是nfs_seqid中关联的RPC任务};
nfs4_state结构的定义如下:
struct nfs4_state { // 属于同一个nfs4_state_owner结构中所有的nfs4_state结构构成了一个链表, // 链表头是nfs4_state_owner->so_states,open_states指向了链表中的相邻元素. struct list_head open_states; /* List of states for the same state_owner */ // 属于同一个inode的所有nfs4_state结构构成了一个链表,链表头是nfs_inode->open_states // inode_states指向了链表中相邻的元素 struct list_head inode_states; /* List of states for the same inode */ // 这是一个链表头,这里保存了nfs4_lock_state结构,表示文件锁结构. struct list_head lock_states; /* List of subservient lock stateids */ // 用户信息 struct nfs4_state_owner *owner; /* Pointer to the open owner */ // 查找条件1 // 文件索引节点 struct inode *inode; /* Pointer to the inode */ // 查找条件2 // flags中包含了很多标志位 unsigned long flags; /* Do we hold any locks? */ // 这是一个自旋锁 spinlock_t state_lock; /* Protects the lock_states list */ // 这是一个顺序锁 seqlock_t seqlock; /* Protects the stateid/open_stateid */ // 这是供delegation使用的stateid. nfs4_stateid stateid; /* Current stateid: may be delegation */ // 这是供OPEN操作使用的stateid. nfs4_stateid open_stateid; /* OPEN stateid */ /* The following 3 fields are protected by owner->so_lock */ // 下面三个变量是以各种权限打开的进程的计数. unsigned int n_rdonly; /* Number of read-only references */ // 只读引用的次数 unsigned int n_wronly; /* Number of write-only references */ // 只写引用的次数 unsigned int n_rdwr; /* Number of read/write references */ // 读写引用的次数 // 这是在服务器端设置的访问权限 fmode_t state; /* State on the server (R,W, or RW) */ atomic_t count; // 这个数据结构的引用计数};
每执行一次OPEN操作,客户端会生成一个stateid,一个stateid代表了一个nfs4_state结构,stateid的结构如下:
struct nfs_stateid4 { __be32 seqid; char other[NFS4_STATEID_OTHER_SIZE]; // 12字节} __attribute__ ((packed));typedef struct nfs_stateid4 nfs4_stateid;
OPEN请求报文使用的数据结构是struct nfs_openargs:
struct nfs_openargs { const struct nfs_fh * fh; // 这是父目录的文件句柄 struct nfs_seqid * seqid; // 这是新分配的nfs_seqid结构, int open_flags; // 打开文件时设置的标志位,如新文件中各用户的访问权限. fmode_t fmode; // 读写权限 __u64 clientid; // 这是客户端的clientid. struct stateowner_id id; // stateowner_id唯一标识了一个nfs4_state_owner结构. union { struct { struct iattr * attrs; /* UNCHECKED, GUARDED */ // 这是一些属性 // typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; // 8 // 当前进程的pid 当前时间 nfs4_verifier verifier; /* EXCLUSIVE */ }; nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */ // 这是要处理的delegation的stateid. fmode_t delegation_type; /* CLAIM_PREVIOUS */ } u; const struct qstr * name; // 这是目标文件的名称 const struct nfs_server *server; /* Needed for ID mapping */ // nfs_server结构. const u32 * bitmask; // 这是服务器支持的文件属性. const u32 * open_bitmap; // 要查找的基本属性信息 __u32 claim; // NFS4_OPEN_CLAIM_NULL struct nfs4_sequence_args seq_args;};OPEN应答报文的数据结构是struct nfs_openres:
struct nfs_openres { nfs4_stateid stateid; // 这是open操作的stateid,共16字节. struct nfs_fh fh; // 这应该是文件的句柄 struct nfs4_change_info cinfo; // 这是父目录的信息 __u32 rflags; // 这是一些标志位信息,包含OPEN4_RESULT_CONFIRM,需要执行OPEN_CONFIRM操作. struct nfs_fattr * f_attr; // 这是返回的文件属性 struct nfs_seqid * seqid; // 这和参数中的seqid相同. const struct nfs_server *server; // 这是nfs_server结构 fmode_t delegation_type; // delegation 类型 FMODE_READ FMODE_WRITE|FMODE_READ nfs4_stateid delegation; // 这里存放的是delegation的stateid. __u32 do_recall; __u64 maxsize; __u32 attrset[NFS4_BITMAP_SIZE]; // 这是解析到的各种属性信息. struct nfs4_string *owner; struct nfs4_string *group_owner; struct nfs4_sequence_res seq_res;};OPEN_CONFIRM操作中的参数和返回值的数据结构如下:
// 这是OPEN_CONFIRM操作的参数struct nfs_open_confirmargs { const struct nfs_fh * fh; // 这是打开文件的句柄 nfs4_stateid * stateid; // 这是open操作返回的stateid struct nfs_seqid * seqid; // 这和open操作的seqid相同.};// 这是OPEN_CONFIRM操作的返回值.struct nfs_open_confirmres { nfs4_stateid stateid; // 经过OPEN_CONFIRM后,stateid变了 struct nfs_seqid * seqid; // 这也和参数中的seqid相同 seqid也变了.};
nfs4_opendata包含了OPEN和OPEN_CONFIRM操作中使用的所有信息。
struct nfs4_opendata { struct kref kref; // 这个数据结构的引用计数 struct nfs_openargs o_arg; // OPEN请求中的参数 struct nfs_openres o_res; // OPEN请求中的返回值 struct nfs_open_confirmargs c_arg; // OPEN_CONFIRM请求中的参数 struct nfs_open_confirmres c_res; // OPEN_CONFIRM请求中的返回值 struct nfs4_string owner_name; // 文件的属主 struct nfs4_string group_name; // 文件的属组 struct nfs_fattr f_attr; // 这是一个文件的属性结构 struct dentry *dir; // 父目录的目录项结构 struct dentry *dentry; // 目标文件的目录项结构 struct nfs4_state_owner *owner; // nfs4_state_owner结构 struct nfs4_state *state; // nfs_state结构 struct iattr attrs; // 这个结构中包含了文件的一些属性,需要修改这些属性 unsigned long timestamp; // 一个时间戳 unsigned int rpc_done : 1; int rpc_status; int cancelled;};
- OPEN操作中的数据结构
- HDFS中的文件open操作
- HDFS中的文件open操作
- Linux内核中的一些基本数据结构操作
- redis中的数据结构基本的操作
- open vswitch研究:基本数据结构
- Open edX数据结构Mysql edxapp
- OPEN命令操作串口
- python:open/文件操作
- python:open/文件操作
- python open 文件操作
- python:open/文件操作
- Open vSwitch基本操作
- python:open/文件操作
- python:open/文件操作
- python:open/文件操作
- python:open 文件操作
- python:open/文件操作
- execl2007和execl2010多窗口显示
- 使用TableView实现多级树型menu
- ORA-00600: internal error code, arguments: [729], [1600], [space leak], [], [], [], [], []
- 浅析SQL 触发器
- PHP中文乱码 解决方案
- OPEN操作中的数据结构
- 如何查看IIS并发连接数
- 硬盘方式安装RedHat 5AS 网卡驱动安装 中文乱码解决 中文输入法安装
- 会话cookie与持久cookie
- GetBuffer(0)
- 详谈UNIX环境进程异常退出
- OpenGL ES2.0 – Iphone开发指引
- Opengl编程低级错误 (转载)
- poj 3686 The Windy's