在2.6.32内核中,vfs的dcache.c文件中,用EXPORT_SYMBOL导出了一系列函数,供内核、文件系统程序使用。
1. EXPORT_SYMBOL(d_alloc);
struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
根据父目录的dentry,以及文件本身的qstr结构体,构造一个子文件或目录的dentry。这个函数主要在lookup的过程中使用
2.EXPORT_SYMBOL(d_alloc_root);
struct dentry * d_alloc_root(struct inode * root_inode)
用来为文件系统根分配dentry,其中inode为文件系统根的inode
3.EXPORT_SYMBOL(d_delete);
void d_delete(struct dentry * dentry)
/*
* When a file is deleted, we have two options:
* - turn this dentry into a negative dentry
* - unhash this dentry and free it.
*
* Usually, we want to just turn this into
* a negative dentry, but if anybody else is
* currently using the dentry or the inode
* we can't do that and we fall back on removing
* it from the hash queues and waiting for
* it to be deleted later when it has no users
*/
这个函数的注释说明如上,当一个文件被删除后,对它的dentry可以有两种操作方式。一种是将将dentry置为负状态(即dentry中d_inode一项被置为NULL),另外一种是将dentry从hash链表上摘掉,并释放空间。通常,在删除一个文件后,会将其dentry转为负状态这种方法,但当还有人在操作该文件(inode的i_count不为0),即该文件的inode不能被置为NULL时,需要将该dentry从hash链表中摘除,在最后一个用户释放该文件后,该dentry才被释放。
4.EXPORT_SYMBOL(d_find_alias);
struct dentry * d_find_alias(struct inode *inode)
用来查找该inode的别名dentry,所谓别名dentry,可以理解为该inode对应的硬连接所使用的dentry。我在看vfs代码的过程中,注意到,vfs对同一个inode的不同硬连接,在lookup的过程中,会生成不同的dentry,这些dentry通过inode结构体下的i_dentry链表穿起来,而在dentry结构体中,同一个inode对应的不同dentry通过d_alias链表串起来。
5.EXPORT_SYMBOL(d_instantiate);
void d_instantiate(struct dentry *entry, struct inode * inode)
用inode来实例化一个dentry
6.EXPORT_SYMBOL(d_invalidate);
int d_invalidate(struct dentry * dentry)
将一个dentry置为无效状态
7.EXPORT_SYMBOL(d_lookup);
struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
根据name和父节点的dentry,对文件进行lookup操作,从而获得子目录或子文件的dentry
8.EXPORT_SYMBOL(d_move)
void d_move(struct dentry * dentry, struct dentry * target)
将dentry移到target上,被vfs_rename_other、vfs_rename_dir调用
9.EXPORT_SYMBOL_GPL(d_materialise_unique);
10.EXPORT_SYMBOL(d_path);
char *d_path(const struct path *path, char *buf, int buflen)
由path结构体获得全路径,保存在缓存buf中,而path结构体存在file指针中
11.EXPORT_SYMBOL(d_prune_aliases);
void d_prune_aliases(struct inode *inode)
将跟当前inode对应的所有dentry释放掉,这里再重复一下dentry跟inode的关系,一个inode可能会对应多个路径(别名,硬链接的情况),当从一个路径访问下来后,就会生成一个dentry,这些dentry都通过inode的下的i_dentry链表挂在一起。
从http://hi.baidu.com/kechen_linux/item/f0ff087553859a316cc37c31这篇博文中摘录了一段,算借花献佛吧
每个dentry对应名字空间中的一个名字. 而每个名字都指向一个inode. 当多个dentry都指向同一个inode的时候就表示这个inode有多个名字, 形成了hardlink. 而这些名字在inode里面由inode->i_dentry链表头连接. 指向同一个inode的多个dentry之间通过dentry->d_alias连接起来.
12.EXPORT_SYMBOL(d_rehash);
void d_rehash(struct dentry * entry)
讲一个dentry加入到哈希链表中,其中的哈希值是由dentry的文件名、父目录dentry的指针计算出来的,具体见d_hash函数
13.EXPORT_SYMBOL(d_splice_alias);
struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
这个函数一般在lookup中调用,
将一个inode与一个负状态的dentry绑定,在这个函数内部,首先要判断inode是否为目录,如果是目录的话,调用__d_find_alias函数搜索一个别名dentry(注意,目录是没有硬链接的),如果找到(说明这个inode的dentry曾经被使用过,而后来dentry变为负状态,但里面的很多内容还可以利用),调用d_rehash更新hash值, 并调用d_move将这个别名dentry的内容移动需要的dentry上。如果__d_find_alias没有找到结果,说明这个inode没有对应的别名dentry,需要调用__d_instantiate、d_rehash将inode绑定到dentry上。如果inode是一个文件的话,直接使用d_add将inode与dentry绑定
14.EXPORT_SYMBOL(d_put)
void dput(struct dentry *dentry)
用来释放dentry占用的资源,首先要判断dentry的引用计数,将其减一,再判断引用计数是否为0,如果存在文件系统层次的d_delete即dentry->d_op->d_delete的话,将会调用dentry->d_op->d_delete来删除dentry,然后执行d_drop将dentry从全局的dentry_hashtable中删除,并调用d_kill清除dentry占用内存资源。如果不存在文件系统的d_delete,则判断dentry->d_lru链表是否为空,如果不为空将其加入到dentry->d_sb->s_dentry_lru,此处的s_dentry_lru是supper block的一个LRU队列dentry_unused,主要是用来放置暂时不用的dentry,等待以后有再次分配。
15.EXPORT_SYMBOL(d_add_ci)
struct dentry* d_add_ci(struct dentry * dentry, struct inode *inode, struct qstr *name)
注释为:
* This is to avoid filling the dcache with case-insensitive names to the
* same inode, only the actual correct case is stored in the dcache for
* case-insensitive filesystems.
这个函数用在对大小不敏感的文件系统(比如ntfs),将大小写不敏感的文件名加入到dentry
16.EXPORT_SYMBOL(find_inode_number)
ino_t find_inode_number(struct dentry *dir, struct qstr *name)
根据文件名,找到它的ino号,需要提供该文件的父目录的dentry指针
17.EXPORT_SYMBOL(have_submounts)
int have_submounts(struct dentry *parent)
检查parent的目录下是否存在挂载点,返回0说明parent下的子目录中,没有挂载点,返回1说明其下可能存在挂载点
18.EXPORT_SYMBOL(shrink_dcache_parent)
void shrink_dcache_parent(struct dentry * parent)
将parent及其子目录、子文件的dentry,从缓存中踢出
19.EXPORT_SYMBOL(shrink_dcache_sb)
void shrink_dcache_sb(struct super_block * sb)
将整个文件系统中的dentry踢出缓存,通常在umount之前调用
20.EXPORT_SYMBOL(d_validate);