1. Client/Owner/State的關(guān)系
一個(gè)Client可以有多個(gè)Owner糖赔,每個(gè)Owner可以擁有多個(gè)State,每個(gè)State代表獲得的一種資源(Open茉盏、Lock、Delegation)码泛。Open owner是針對(duì)open的owner烹笔。
2. Open Owner
在OPEN請(qǐng)求中裳扯,Client傳給Server24Byte的Owner信息。OPEN請(qǐng)求會(huì)返回state id谤职。以后SETATTR/READ/WRITE時(shí)候饰豺,需要使用state id。
2. 1 open owner的由來(lái)
下面是ganesha打出的log,這個(gè)owner是由NFS Kernel Client分配的允蜈。
open4_open_owner : owner=(24:0x6f70656e2069643a0000002b00000000000100bd38d66fb8)
2.2 open owner的作用
每次進(jìn)行open的時(shí)候冤吨,ganesha內(nèi)部都會(huì)維護(hù)open owner和state的數(shù)據(jù)結(jié)構(gòu)。在open返回的時(shí)候收到stateid作為收據(jù)饶套。以后每次read/write的時(shí)候漩蟆,會(huì)根據(jù)stateid找到對(duì)應(yīng)的open owner和state數(shù)據(jù)結(jié)構(gòu)。然后判斷state是否沖突妓蛮。
3 open的過(guò)程
封裝在nfs4_op_open
里怠李。
- 調(diào)用
nfs_client_id_get_confirmed
,通過(guò)傳進(jìn)來(lái)的clientid,得到confirmed clientid信息仔引,即nfs_client_id_t
扔仓。 - 調(diào)用
open4_open_owner
,通過(guò)clientid和傳進(jìn)來(lái)的24byte open owner咖耘,得到ganesha自己的owner對(duì)象翘簇,即state_owner_t
。第一次調(diào)用open4_open_owner儿倒,創(chuàng)建新的owner版保,以后調(diào)用都從key/value pair里取。 - 調(diào)用
open4_ex
夫否,根據(jù)clientid和open owner得到ganesha自己的state對(duì)象彻犁,即state_t
。第一次調(diào)用創(chuàng)建新的state對(duì)象凰慈,并通過(guò)state_add_impl()
將state插入owner隊(duì)列中汞幢。以后調(diào)用從key/value pair里取。state由owner+file_obj唯一確定微谓。 - 調(diào)用
update_stateid
森篷,設(shè)置返回值,其中包括stateid豺型。
3.1 open4_open_owner()分析
- 將24byte的state owner轉(zhuǎn)換成ganesha自己數(shù)據(jù)結(jié)構(gòu)
state_owner_t
仲智。這個(gè)關(guān)系記錄在key/value pair中 - 如果key/value pair中不存在這個(gè)key,則是新的姻氨,不需要檢查什么钓辆。
- 如果不是新的,需要簡(jiǎn)單檢查一下。
以下是ganesha的log:
Open: STATE_OPEN_OWNER_NFSV4 0x7efe580207f0: clientid={0x7efe40001990 ClientID={Epoch=0x5c987c1f Counter=0x00000001} CONFIRMED Client={0x7efe400018a0 name=(27:Linux NFSv4.1 ubuntu-xenial) refcount=1} t_delta=0 reservations=1 refcount=4} owner=(24:0x6f70656e2069643a0000002b000000000001855ef8aa8e36) confirmed=1 seqid=0 refcount=1
3.2 open4_ex()分析
- 調(diào)用
alloc_state
創(chuàng)建state對(duì)象前联。調(diào)用FSAL層的open函數(shù)判斷state對(duì)象是否滿足需求功戚。 - 將這個(gè)open state傳進(jìn)相應(yīng)的FSAL的open2函數(shù)里。
- 調(diào)用
state_add_impl
將這個(gè)open state加入到open state的list里(對(duì)于open owner,這個(gè)list頂多有一個(gè)元素)蛀恩。
4 read/write/lock/unlock
OPEN之后的read/write/lock/unlock都會(huì)傳進(jìn)來(lái)stateid疫铜,會(huì)根據(jù)這個(gè)stateid判斷是否沖突。
邏輯封裝在nfs4_Check_Stateid()里
stateid => state => open file object 和state owner
5. 相關(guān)數(shù)據(jù)結(jié)構(gòu)
struct nfs_client_id_t {
clientid4 cid_clientid; //clientid
verifier4 cid_verifier; //verifier,重啟后會(huì)變化
...
nfs_client_record_t *cid_client_record; //指回nfs_client_record_t
struct glist_head cid_openowners; //open owner list
struct glist_head cid_lockowners; //lock owners list
pthread_mutex_t cid_mutex;
...
struct gsh_client *gsh_client; //
};
//同一個(gè)client,針對(duì)不同資源双谆,可以有多個(gè)owner壳咕。
struct state_owner_t {
state_owner_type_t so_type; //owner類型,lock or open
struct glist_head so_lock_list; //Locks for this owner
pthread_mutex_t so_mutex;
int32_t so_refcount; //Reference count for lifecyce management
int so_owner_len; //Length of owner name
char *so_owner_val; //Owner name
union {
state_nfs4_owner_t so_nfs4_owner; // All NFSv4 state owners
} so_owner;
};
struct state_nfs4_owner_t {
clientid4 so_clientid; //clientid
nfs_client_id_t *so_clientrec; //confirm and unconfirm
...
struct glist_head so_state_list; //這個(gè)owner所擁有的state
...
};
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
pthread_mutex_t state_mutex; /**< Mutex protecting following pointers */
struct gsh_export *state_export; /**< Export this entry belongs to */
state_owner_t *state_owner; //對(duì)應(yīng)的owner
struct fsal_obj_handle *state_obj; //對(duì)應(yīng)的file object
struct fsal_export *state_exp; /**< FSAL export */
union state_data state_data; //根據(jù)state類型,對(duì)應(yīng)不同數(shù)據(jù)
enum state_type state_type;//state類型顽馋,STATE_TYPE_SHARE谓厘,STATE_TYPE_DELEG,STATE_TYPE_LOCK
u_int32_t state_seqid; /**< The NFSv4 Sequence id */
int32_t state_refcount; /**< Refcount for state_t objects */
char stateid_other[OTHERSIZE]; //state id最重要的部分寸谜,可以通過(guò)它找到state
...
};
Owner的相關(guān)函數(shù):
- create_nfs4_owner: 根據(jù)clientid和client傳進(jìn)來(lái)的24Byte的open owner竟稳,創(chuàng)建Server端的
state_owner_t
- open4_open_owner: 調(diào)用create_nfs4_owner,如果owner已經(jīng)創(chuàng)建過(guò)熊痴,返回錯(cuò)誤他爸。