-
/**
-
* d_alloc - allocate a dcache entry
-
* @parent: parent of entry to allocate
-
* @name: qstr of the name
-
*
-
* Allocates a dentry. It returns %NULL if there is insufficient memory
-
* available. On a success the dentry is returned. The name passed in is
-
* copied and the copy passed in may be reused after this call.
-
*/
-
-
struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
-
{
-
struct dentry *dentry;
-
char *dname;
/* 分配一块内存
dentry结构里面有一个d_iname[DNAME_INLINE_LEN_MIN]数组 */
-
dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
-
if (!dentry)
-
return NULL;
/* 如果路径分量name->name字符串太长,超过了DNAME_INLINE_LEN_MIN(128字节),那么dentry->d_iname就不能用来保存name->name了。需要另外分配一块内存来 */
-
if (name->len > DNAME_INLINE_LEN-1) {
-
dname = kmalloc(name->len + 1, GFP_KERNEL);
-
if (!dname) {
-
kmem_cache_free(dentry_cache, dentry);
-
return NULL;
-
}
-
} else {
-
dname = dentry->d_iname;
-
}
-
dentry->d_name.name = dname;
/* 将qstr *name的内容copy过来 */
-
dentry->d_name.len = name->len;
-
dentry->d_name.hash = name->hash;
-
memcpy(dname, name->name, name->len);
-
dname[name->len] = 0;
/* dentry刚刚分配的状态是DCACHE_UNHASHED,因为它还没有链入dentry_hashtable[dentry->d_name.hash]的hash链,等dentry在文件系统的lookup函数中填充完毕后,会将dentry通过d_hash链入hashtdentry_able[dentry->d_name.hash],链入以后才取消DCACHE_UNHASHED标志
比如procfs的lookup函数proc_root_lookup
调用流程:
proc_root_lookup->
proc_lookup->
proc_lookup_de
在proc_lookup_de函数里面,通过d_add将dentry链入hashtdentry_able[dentry->d_name.hash],并取消dentry的DCACHE_UNHASHED标志
if (inode) {
dentry->d_op = &proc_dentry_operations;
d_add(dentry, inode);
return NULL;
}
*/
-
atomic_set(&dentry->d_count, 1);
-
dentry->d_flags = DCACHE_UNHASHED;
-
spin_lock_init(&dentry->d_lock);
-
dentry->d_inode = NULL;
-
dentry->d_parent = NULL;
-
dentry->d_sb = NULL;
-
dentry->d_op = NULL;
-
dentry->d_fsdata = NULL;
-
dentry->d_mounted = 0;
-
INIT_HLIST_NODE(&dentry->d_hash);
-
INIT_LIST_HEAD(&dentry->d_lru);
-
INIT_LIST_HEAD(&dentry->d_subdirs);
-
INIT_LIST_HEAD(&dentry->d_alias);
/* dentry在分配时已经设置其parent entry */
-
if (parent) {
-
dentry->d_parent = dget(parent);
-
dentry->d_sb = parent->d_sb;
-
} else {
-
INIT_LIST_HEAD(&dentry->d_u.d_child);
-
}
-
-
/* dentry在分配时还要通过d_u.d_child链入parent 的d_subdirs中 */
-
spin_lock(&dcache_lock);
-
if (parent)
-
list_add(&dentry->d_u.d_child, &parent->d_subdirs);
-
dentry_stat.nr_dentry++;
-
spin_unlock(&dcache_lock);
-
-
return dentry;
-
}