OPEN(二)

        这篇文章中我们接着讲解服务器端的处理程序,首先介绍几个与OPEN操作有关的数据结构。第1个数据结构是struct nfs4_openowner,这个数据结构跟客户端的nfs4_state_owner相对应,保存了一个用户的信息,这个数据结构的定义如下:

struct nfs4_openowner {
        struct nfs4_stateowner  oo_owner; /* must be first field */
        // 每个nfs4_client结构中包含多个nfs4_openowner结构,这些结构构成了一个链表
        // oo_perclient指向链表中相邻的元素.
        struct list_head        oo_perclient;
        /*
         * We keep around openowners a little while after last close,
         * which saves clients from having to confirm, and allows us to
         * handle close replays if they come soon enough.  The close_lru
         * is a list of such openowners, to be reaped by the laundromat
         * thread eventually if they remain unused:
         */
        // 所有空闲未用的nfs4_openowner结构保存在一个全局链表(close_lru)中.
        struct list_head        oo_close_lru;
        struct nfs4_ol_stateid *oo_last_closed_stid;    // 最后使用的nfs4_ol_stateid结构
        // 放置到close_lru链表中的时间.
        time_t                  oo_time; /* time of placement on so_close_lru */
// 表示这个nfs4_openowner结构已经确认过了,可以使用了.
#define NFS4_OO_CONFIRMED   1           // OPEN_CONFIRM
// 设置这个标志位后表示下次就需要释放oo_last_closed_stid了
#define NFS4_OO_PURGE_CLOSE 2
// 这是一个新创建的nfs4_openowner结构,还不能使用.
#define NFS4_OO_NEW         4           // OPEN
        unsigned char           oo_flags;
};
        nfs4_openowner结构中第一个字段的数据类型是nfs4_stateowner,这个结构的定义如下:

struct nfs4_stateowner {
        // 所有的nfs4_stateowner(nfs4_openowner和nfs4_lockowner)保存在一个hash表中(ownerstr_hashtbl)
        struct list_head        so_strhash;   /* hash by op_name */
        // 这是一个链表,链表中的数据结构是nfs4_ol_stateid,表示了用户打开的所有文件.
        struct list_head        so_stateids;    // 
        struct nfs4_client *    so_client;      // 这个nfs4_stateowner结构所属的客户端
        /* after increment in ENCODE_SEQID_OP_TAIL, represents the next
         * sequence id expected from the client: */
        // 这是一个序号,这个seqid和nfs4_state_owner->so_seqid.counter对应.
        u32                     so_seqid;       // 每次操作都会更新seqid
        // 这表示了一个用户    open id:<server->s_dev><nfs_seqid_counter->create_time><nfs_seqid_counter->owner_id>
        // so_owner保存了这次OPEN操作的名称,从OPEN请求报文中解析得到的.
        struct xdr_netobj       so_owner;     /* open owner name */
        struct nfs4_replay      so_replay;
        bool                    so_is_open_owner;       // 这是一个nfs4_opwnowner结构
};
        因此nfs4_stateowner结构中的信息也是nfs4_openowner结构中的信息,那么为什么要把这些信息独立出来组成一个新的数据结构呢?因为我们现在只讲到了OPEN操作,还没有讲解LOCK操作。服务器端保存LOCK信息的数据结构是nfs4_lockowner,nfs4_openowner和nfs4_lockowner有些相似之处,这些相似的信息提取出来构成了nfs4_stateowner。

        与客户端中nfs4_state相对应的数据结构是nfs4_ol_stateid,这个数据结构保存了一次OPEN操作的信息,这个数据结构的定义如下:

struct nfs4_ol_stateid {
        // 这里包含了这个stateid的类型和归属的客户端(nfs4_client)
        struct nfs4_stid    st_stid; /* must be first field */
        // 同一个nfs4_file结构中所有的nfs4_ol_stateid结构构成了一个链表。
        // st_perfile指向了链表中相邻的元素.
        struct list_head              st_perfile;
        // 一个nfs4_stateowner结构中包含多个nfs4_ol_stateid结构,st_perstateowner指向链表中下一个元素。
        struct list_head              st_perstateowner;
        // 这是一个链表,链表中的数据结构是nfs4_lockowner.
        struct list_head              st_lockowners;
        // 属于的nfs4_stateowner结构,有可能是nfs4_openowner结构,也有可能是nfs4_lockowner结构.
        struct nfs4_stateowner      * st_stateowner;
        // 这个nfs4_ol_stateid结构所属于的nfs4_file
        struct nfs4_file            * st_file;
        // 这是访问权限标志位
        unsigned long                 st_access_bmap;   // NONE READ WRITE BOTH
        unsigned long                 st_deny_bmap;     // NOEN READ WRITE BOTH
        // 如果这是一个(nfs4_lockowner-->nfs4_ol_stateid),指向所在的(nfs4_openlock->nfs4_ol_stateid)
        struct nfs4_ol_stateid         * st_openstp;
};


NFS服务器端还定义了一个数据结构nfs4_file,这个数据结构表示一个文件,包含了文件的一些信息,如文件索引节点等。每个文件用一个nfs4_file结构表示,这个数据结构定义如下:

struct nfs4_file {
        atomic_t                fi_ref;         // 这个结构的引用计数
        // fi_hash将这个nfs4_file结构链接到file_hashtbl中
        // file_hashtbl是一个全局hash表,保存了系统中所有的nfs4_file结构.
        struct list_head        fi_hash;    /* hash by "struct inode *" */
        // 这个文件上关联了很多个nfs4_ol_stateid结构,这是链表头.
        struct list_head        fi_stateids;
        // 这个文件上还关联了很多nfs4_delegation结构,这些delegation共用一个租借锁
        // 比如多个客户端以只读权限打开同一个文件,这是delegation的链表头.
        struct list_head        fi_delegations;
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
        // 这个文件可能打开了多次,有多个文件对象结构,保存在这里.
        struct file *           fi_fds[3];
        /*
         * Each open or lock stateid contributes 0-4 to the counts
         * below depending on which bits are set in st_access_bitmap:
         *     1 to fi_access[O_RDONLY] if NFS4_SHARE_ACCES_READ is set
         *   + 1 to fi_access[O_WRONLY] if NFS4_SHARE_ACCESS_WRITE is set
         *   + 1 to both of the above if NFS4_SHARE_ACCESS_BOTH is set.
         */
        // 这是各种权限的引用计数.
        atomic_t                fi_access[2];
        // 关联到的文件对象
        struct file             *fi_deleg_file;
        // 这是一个租借锁,NFSv4用租借锁机制实现delegation
        // 所有的delegation共用同一个租借锁
        struct file_lock        *fi_lease;              // 这是一个文件锁结构
        // 这应该是fi_lease指针的引用数量,这是一个租借锁
        atomic_t                fi_delegees;
        struct inode            *fi_inode;              // 这是文件的索引节点结构
        // 文件锁是否发生了冲突,当服务器删除租借锁时就会先将fi_had_conflict设置为true,
        // 这时客户端就不能申请delegation了.
        bool                    fi_had_conflict;
};



    NFS服务器端负责解析OPEN请求报文的函数是nfsd4_decode_open(),这个函数将解析结果填充在数据结构nfsd4_open中,这个数据结构的定义如下:
struct nfsd4_open {
        // CLAIM_DELEGATE_CUR
        u32             op_claim_type;      /* request */
        struct xdr_netobj op_fname;         /* request - everything but CLAIM_PREV */
        u32             op_delegate_type;   /* request - CLAIM_PREV only */
        // NFS4_OPEN_CLAIM_DELEGATE_CUR中这是客户端传过来的delegation的stateid
        stateid_t       op_delegate_stateid; /* request - response */
        u32             op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
        u32             op_create;          /* request */
        u32             op_createmode;      /* request */
        u32             op_bmval[3];        /* request */
        struct iattr    iattr;              /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
        nfs4_verifier   op_verf __attribute__((aligned(32)));
                                            /* EXCLUSIVE4 */
        clientid_t      op_clientid;        /* request */
        struct xdr_netobj op_owner;           /* request */
        u32             op_seqid;           /* request */
        u32             op_share_access;    /* request */
        u32             op_share_deny;      /* request */
        u32             op_deleg_want;      /* request */
        stateid_t       op_stateid;         /* response */
        u32             op_recall;          /* recall */
        struct nfsd4_change_info  op_cinfo; /* response */
        u32             op_rflags;          /* response */
        bool            op_truncate;        /* used during processing */
        bool            op_created;         /* used during processing */
        struct nfs4_openowner *op_openowner; /* used during processing */
        struct nfs4_file *op_file;          /* used during processing */
        struct nfs4_ol_stat
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值