Linux Progamming

nfs-ganesha - Lock

2019-02-13  本文已影响0人  帆子_8c3a

Lock Owner

Lock owner是Linux Kernel Client分配的大小20Byte,表示owner的。对于相同的client下,owner唯一。

nfs4_op_lock

  1. 根据传进来的20byte owner创建owner对象。如果是第一次,创建一个新的,否则从key/vaule pair里取。
  2. 获取lock state,它由obj+lock_owner唯一确定。
  3. 如果lock state为空,则调用state_add_impl,创建一个lock state,并插入到owner list里

NFS4协议是有状态的,所以nfs-ganesha需要保存这些状态,这些状态可以理解为资源、状态。在NFS4的协议里stateid就对应一个文件的某种lock。这里包括

enum state_type {
    STATE_TYPE_NONE = 0,
    STATE_TYPE_SHARE = 1,  //Share reservation,针对Windows客户
    STATE_TYPE_DELEG = 2,  //delegation
    STATE_TYPE_LOCK = 3,    //range lock
    STATE_TYPE_LAYOUT = 4,
    STATE_TYPE_NLM_LOCK = 5,
    STATE_TYPE_NLM_SHARE = 6,
    STATE_TYPE_9P_FID = 7,
};
/**
 * @brief Structure representing a single NFSv4 state
 *
 * Each state is identified by stateid and represents some resource or
 * set of resources.
 *
 * The lists are protected by the state_lock
 */

struct state_t {
    struct glist_head state_list;   /**< List of states on a file */
    struct glist_head state_owner_list;  /**< List of states for an owner */
    struct glist_head state_export_list; /**< List of states on the same
                         export */
#ifdef DEBUG_SAL
    struct glist_head state_list_all;    /**< Global list of all stateids */
#endif
    pthread_mutex_t state_mutex; /**< Mutex protecting following pointers */
    struct gsh_export *state_export; /**< Export this entry belongs to */
    /* Don't re-order or move these next two.  They are used for hashing */
    state_owner_t *state_owner; /**< State Owner related to state */
    struct fsal_obj_handle *state_obj; /**< owning object */
    struct fsal_export *state_exp;  /**< FSAL export */
    union state_data state_data;
    enum state_type state_type;
    u_int32_t state_seqid;      /**< The NFSv4 Sequence id */
    int32_t state_refcount;     /**< Refcount for state_t objects */
    char stateid_other[OTHERSIZE];  /**< "Other" part of state id,
                       used as hash key */
    struct state_refer state_refer; /**< For NFSv4.1, track the
                       call that created a
                       state. */
};

在使用lock state时候,用state_hdl->state_lock保护。其中的state_seqid(32bit)+stateid_other(96bit)组成128bit的stateid。

    PTHREAD_RWLOCK_wrlock(&obj->state_hdl->state_lock);
...
    /* Now we have a lock owner and a stateid.  Go ahead and push
     * lock into SAL (and FSAL). */
    state_status = state_lock(obj,
                  lock_owner,
                  lock_state,
                  blocking,
                  NULL, /* No block data for now */
                  &lock_desc,
                  &conflict_owner,
                  &conflict_desc);
...
    PTHREAD_RWLOCK_unlock(&obj->state_hdl->state_lock);

stateid相关函数
update_stateid()
nfs4_Check_Stateid()
nfs4_State_Get_Obj() //get state from obj and owner
nfs4_State_Get_Pointer() //get state from other
nfs4_State_Set() //Add the state to the related hashtable
state_add()
state_del()
state_set()
state_lock()
state_add_impl()

STATE_TYPE_SHARE

每次open会获得一个STATE_TYPE_SHARE类型的state_t。

lock

上一篇下一篇

猜你喜欢

热点阅读