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;};
原创粉丝点击