目录项高速缓存

缓存状态

缓存管理

vfs dcache函数

在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);

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值