inode是glusterfs中重要的資料結構之一, glusterfs用它來表示檔案系統中的inode,但二者不是 等價的。
inode資料結構
先粗略看下inode資料結構定義,對它有個整體印象
typedef struct _inode inode_t;
struct _inode {
inode_table_t *table; /* the table this inode belongs to */
uuid_t gfid;
gf_lock_t lock;
uint64_t nlookup;
uint32_t ref; /* reference count on this inode */
ia_type_t ia_type; /* what kind of file */
struct list_head fd_list; /* list of open files on this inode */
struct list_head dentry_list; /* list of directory entries for this inode*/
struct list_head hash; /* hash table pointers */
struct list_head list; /* active/lru/purge */
struct _inode_ctx *_ctx; /* replacement for dict_t *(inode->ctx) */
};
其中 一個叫list的成員十分重要,将在後面提到,它以節點的形式插入active list或lru list或purge list中
成員hash, list都是一個節點,他們不存放任何資料,隻是用來表示各種連結清單關系 。
成員fd_list, dentry_list 是真正的連結清單
inode與dentry的關系
在inode.c檔案中,高頻詞除了inode外,還有dentry。它對應與檔案系統中目錄項。
dentry與inode是多對一的關系,很多dentry可以指向同一個inode。 dentry主要的資料是目錄項的名字。
typedef struct _dentry dentry_t;
struct _dentry {
struct list_head inode_list; /* list of dentries of inode */
struct list_head hash; /* hash table pointers */
inode_t *inode; /* inode of this directory entry */
char *name; /* name of the directory entry */
inode_t *parent; /* directory of the entry */
};
同上,inode_list,hash也隻是一個節點。
inode.c中,另一個資料結構是inode_table, 它相當于是一個總管,管理所有inode的狀态/lru/hash/記憶體配置設定/。定義請察看源檔案。
inode 的狀态轉移圖
------ref-------> [active]
/ / \
inode_create ---> [lru] <------unref----- ---unref-retire------->[purge] ----> destory
\ /
-------table-prune--(lru_size>lru_limit)--->--
注:lru表示Least Recently Used最近最少使用算法, 網上一堆,這裡就不贅述了。
其中active,lru,purge代表inode的三個狀态, 在inode_table中定義有3個連結清單與之對應。
當inode->list在某個連結清單中時,就代表inode處于這種狀态。
list_move函數負責将連結清單節點在不同的連結清單中轉移。如
list_move (&inode->list, &inode->table->active);
就表示将inode的狀态設為active。
inode_ctx
ctx(context) 存放inode的一些私有資料,它的定義很有意思:
struct _inode_ctx {
union {
uint64_t key;
xlator_t *xl_key;
};
union {
uint64_t value1;
void *ptr1;
};
union {
uint64_t value2;
void *ptr2;
};
};
它有3個union, union在C語言中并不常見,這麼高密度的出現在這裡,我猜測是為了記憶體對齊。這樣ctx結構體的大小不會随着作業系統是32位還是64位而變化,一定為3*64bit。
hash & grep
為了提高 inode和dentry的查找速度,作者都對他們做了hash:
inode使用gfid 作為hash key; dentry使用name 作為hash key。
hash表存放在inode_table中: inode_hash[], name_hash[]
hash查找函數為: inode_grep(...), dentry_grep(...)