Lock Owner
Lock owner是Linux Kernel Client分配的大小20Byte,表示owner的。对于相同的client下,owner唯一。
nfs4_op_lock
- 根据传进来的20byte owner创建owner对象。如果是第一次,创建一个新的,否则从key/vaule pair里取。
- 获取lock state,它由obj+lock_owner唯一确定。
- 如果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
- state_lock <= nfs4_op_lock
- state_unlock
- state_cancel
网友评论