1.dentry_hashtable的定义
dentry_hashtable用来方便虚拟文件系统vfs快速索引dentry。在2.6.32内核中,它在dcache.c文件中定义:
static struct hlist_head *dentry_hashtable __read_mostly;
hlist_head为hash链表头的数据类型,关于此数据类型的详细描述,可以参考 http://blog.csdn.net/ronliu/article/details/6425368
__read_mostly宏用来提示系统此处会被经常读取,系统加载时需要将其读入cache中
2.dentry_hashtable的初始化
dentry_hashtable的初始化在dcache_init_early函数和dcache_init函数中会涉及,初始化的函数为:
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
sizeof(struct hlist_head),
dhash_entries,
13,
0,
&d_hash_shift,
&d_hash_mask,
0);
for (loop = 0; loop < (1 << d_hash_shift); loop++)
INIT_HLIST_HEAD(&dentry_hashtable[loop]);
3.d_hash函数(叫d_hash的有两个东西,一个是struct dentry下的一个成员变量struct hlist_node d_hash,是hash链表的一个结点,另一个d_hash则是一个函数用来获得dentry在dentry_hashtable上所在hash桶的位置)
d_hash函数的参数中,parent为其父目录的dentry指针、hash为文件名的hash值,在__link_path_walk函数中,该hash值的计算方法为:
this.name = name;
c = *(const unsigned char *)name;
hash = init_name_hash();
do {
name++;
hash = partial_name_hash(c, hash);
c = *(const unsigned char *)name;
} while (c && (c != '/'));
this.len = name - (const char *) this.name;
this.hash = end_name_hash(hash);
核心思想是通过partial_name_hash函数对字符逐个计算hash值,再end_name_hash生成最后的hash值
d_hash函数的实现如下:
static inline struct hlist_head *d_hash(struct dentry *parent, unsigned long hash)
{
hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
hash = hash ^ ((hash ^ GOLDEN_RATIO_PRIME) >> D_HASHBITS);
return dentry_hashtable + (hash & D_HASHMASK);
}
注意,其中的D_HASHMASK、D_HASHBITS宏,其定义为:
#define D_HASHBITS d_hash_shift
#define D_HASHMASK d_hash_mask
这两个值在alloc_large_system_hash函数中用到了,所以d_hash函数返回值实际上是一个hash桶的指针
4.d_rehash函数
d_rehash函数会调用d_hash,将dentry->d_hash挂到dentry_hashtable上特定的hash桶中,并将dentry->d_flag中的DCACHE_UNHASHED标志位清除。
5.d_drop函数
会将dentry->d_flag置为DCACHE_UNHASHED,并将dentry->d_hash从hash链表上摘除
参考: http://www.cnitblog.com/ygb/articles/8795.html