inode是glusterfs中重要的数据结构之一, glusterfs用它来表示文件系统中的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.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/内存分配/。定义请察看源文件。
------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。
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。
为了提高 inode和dentry的查找速度,作者都对他们做了hash:
inode使用gfid 作为hash key; dentry使用name 作为hash key。
hash表存放在inode_table中: inode_hash[], name_hash[]
hash查找函数为: inode_grep(...), dentry_grep(...)