Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache
在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。
(内核:2.4.37)
为什么这个缓冲区会存在,不好意思,我说了废话,当然和前面一样的,为了提升效率,例如我们写一个.c的helloworld文件,简单的过程是编辑,编译,执行。。。那么这个过程都是需要找到所在的文件位置的,如果每次都从根开始找并且还有构造相应的目录项对象,是很费时的,所以将目录项一般也都是缓存起来的~~~
Ps:dentry结构
- 67 struct dentry {
- 68 atomic_t d_count;
- 69 unsigned int d_flags;
- 70 struct inode * d_inode; /* Where the name belongs to - NULL is negative */
- 71 struct dentry * d_parent; /* parent directory */
- 72 struct list_head d_hash; /* lookup hash list */
- 73 struct list_head d_lru; /* d_count = 0 LRU list */
- 74 struct list_head d_child; /* child of parent list */
- 75 struct list_head d_subdirs; /* our children */
- 76 struct list_head d_alias; /* inode alias list */
- 77 int d_mounted;
- 78 struct qstr d_name;
- 79 unsigned long d_time; /* used by d_revalidate */
- 80 struct dentry_operations *d_op;
- 81 struct super_block * d_sb; /* The root of the dentry tree */
- 82 unsigned long d_vfs_flags;
- 83 void * d_fsdata; /* fs-specific data */
- 84 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
- 85 };
和前面的一样,这个也涉及到几个相应的链表来管理,那么看看/fs/dcache.c中哪些链表被定义了。
- 52 static struct list_head *dentry_hashtable;
- 53 static LIST_HEAD(dentry_unused);
哈希链表 :从中能够快速获取与给定的文件名和目录名对应的目录项对象。
“未使用”链表:所有未使用 目录项对象都存放在一个LRU的双向链表。LRU链表的首元素和尾元素的地址存放在变量dentry_unused中的next 域和prev域中。目录项对象的d_lru域包含的指针指向该链表中相邻目录的对象。
简单的看一下dcache初始化过程:
- 1181 static void __init dcache_init(unsigned long mempages)
- 1182 {
- 1183 struct list_head *d;
- 1184 unsigned long order;
- 1185 unsigned int nr_hash;
- 1186 int i;
- 1187
- 1188 /*
- 1189 * A constructor could be added for stable state like the lists,
- 1190 * but it is probably not worth it because of the cache nature
- 1191 * of the dcache.
- 1192 * If fragmentation is too bad then the SLAB_HWCACHE_ALIGN
- 1193 * flag could be removed here, to hint to the allocator that
- 1194 * it should not try to get multiple page regions.
- 1195 */
- 1196 dentry_cache = kmem_cache_create("dentry_cache",
- 1197 sizeof(struct dentry),
- 1198 0,
- 1199 SLAB_HWCACHE_ALIGN,
- 1200 NULL, NULL);
- 1201 if (!dentry_cache)
- 1202 panic("Cannot create dentry cache");
- 1203
- 1204 #if PAGE_SHIFT < 13
- 1205 mempages >>= (13 - PAGE_SHIFT);
- 1206 #endif
- 1207 mempages *= sizeof(struct list_head);
- 1208 for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
- 1209 ;
- 1210
- 1211 do {
- 1212 unsigned long tmp;
- 1213
- 1214 nr_hash = (1UL << order) * PAGE_SIZE /
- 1215 sizeof(struct list_head);
- 1216 d_hash_mask = (nr_hash - 1);
- 1217
- 1218 tmp = nr_hash;
- 1219 d_hash_shift = 0;
- 1220 while ((tmp >>= 1UL) != 0UL)
- 1221 d_hash_shift++;
- 1222
- 1223 dentry_hashtable = (struct list_head *)
- 1224 __get_free_pages(GFP_ATOMIC, order);
- 1225 } while (dentry_hashtable == NULL && --order >= 0);
- 1226
- 1227 printk(KERN_INFO "Dentry cache hash table entries: %d (order: %ld, %ld bytes)\n",
- 1228 nr_hash, order, (PAGE_SIZE << order));
- 1229
- 1230 if (!dentry_hashtable)
- 1231 panic("Failed to allocate dcache hash table\n");
- 1232
- 1233 d = dentry_hashtable;
- 1234 i = nr_hash;
- 1235 do {
- 1236 INIT_LIST_HEAD(d);
- 1237 d++;
- 1238 i--;
- 1239 } while (i);
- 1240 }
上面代码就是相当于分配cache空间,并将hash表什么的都初始化了~~~
下面看一下怎么分配一个目录项对象,涉及函数d_alloc:
- 580 /**
- 581 * d_alloc - allocate a dcache entry
- 582 * @parent: parent of entry to allocate
- 583 * @name: qstr of the name
- 584 *
- 585 * Allocates a dentry. It returns %NULL if there is insufficient memory
- 586 * available. On a success the dentry is returned. The name passed in is
- 587 * copied and the copy passed in may be reused after this call.
- 588 */
- 589
- 590 struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
- 591 {
- 592 char * str;
- 593 struct dentry *dentry;
- 594
- 595 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); /* 分配一个dentry空间 */
- 596 if (!dentry)
- 597 return NULL;
- 598
- 599 if (name->len > DNAME_INLINE_LEN-1) {
- 600 str = kmalloc(NAME_ALLOC_LEN(name->len), GFP_KERNEL);
- 601 if (!str) {
- 602 kmem_cache_free(dentry_cache, dentry);
- 603 return NULL;
- 604 }
- 605 } else
- 606 str = dentry->d_iname;
- 607 /* 复制name */
- 608 memcpy(str, name->name, name->len);
- 609 str[name->len] = 0;
- 610 /* 下面根据dentr的字段进行赋值,具体的字段意义见:http://blog.csdn.net/shanshanpt/article/details/38943731 */
- 611 atomic_set(&dentry->d_count, 1);
- 612 dentry->d_vfs_flags = 0;
- 613 dentry->d_flags = 0;
- 614 dentry->d_inode = NULL;
- 615 dentry->d_parent = NULL;
- 616 dentry->d_sb = NULL;
- 617 dentry->d_name.name = str;
- 618 dentry->d_name.len = name->len;
- 619 dentry->d_name.hash = name->hash;
- 620 dentry->d_op = NULL;
- 621 dentry->d_fsdata = NULL;
- 622 dentry->d_mounted = 0;
- 623 INIT_LIST_HEAD(&dentry->d_hash);
- 624 INIT_LIST_HEAD(&dentry->d_lru);
- 625 INIT_LIST_HEAD(&dentry->d_subdirs);
- 626 INIT_LIST_HEAD(&dentry->d_alias);
- 627 if (parent) {
- 628 dentry->d_parent = dget(parent);
- 629 dentry->d_sb = parent->d_sb;
- 630 } else
- 631 INIT_LIST_HEAD(&dentry->d_child);
- 632
- 633 spin_lock(&dcache_lock);
- 634 if (parent)
- 635 list_add(&dentry->d_child, &parent->d_subdirs);
- 636 dentry_stat.nr_dentry++;
- 637 spin_unlock(&dcache_lock);
- 638
- 639 return dentry;
- 640 }
- 641
下面看看怎么去寻找一个目录,涉及函数d_lookup:
- 698 /**
- 699 * d_lookup - search for a dentry
- 700 * @parent: parent dentry
- 701 * @name: qstr of name we wish to find
- 702 *
- 703 * Searches the children of the parent dentry for the name in question. If
- 704 * the dentry is found its reference count is incremented and the dentry
- 705 * is returned. The caller must use d_put to free the entry when it has
- 706 * finished using it. %NULL is returned on failure.
- 707 */
- 708
- 709 struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
- 710 {
- 711 unsigned int len = name->len;
- 712 unsigned int hash = name->hash;
- 713 const unsigned char *str = name->name;
- 714 struct list_head *head = d_hash(parent,hash); /* 通过hash值计算得到目录项缓冲区位置的head */
- 715 struct list_head *tmp;
- 716
- 717 spin_lock(&dcache_lock);
- 718 tmp = head->next;
- 719 for (;;) { /* 下面循环找到对应的dentry */
- 720 struct dentry * dentry = list_entry(tmp, struct dentry, d_hash);
- 721 if (tmp == head)
- 722 break;
- 723 tmp = tmp->next;
- 724 if (dentry->d_name.hash != hash)
- 725 continue;
- 726 if (dentry->d_parent != parent)
- 727 continue;
- 728 if (parent->d_op && parent->d_op->d_compare) {
- 729 if (parent->d_op->d_compare(parent, &dentry->d_name, name))
- 730 continue;
- 731 } else {
- 732 if (dentry->d_name.len != len)
- 733 continue;
- 734 if (memcmp(dentry->d_name.name, str, len))
- 735 continue;
- 736 }
- 737 __dget_locked(dentry);
- 738 dentry->d_vfs_flags |= DCACHE_REFERENCED; /* 找到,那么添加引用就OK */
- 739 spin_unlock(&dcache_lock);
- 740 return dentry; /* 返回找到的dentry。里面有我们需要的信息例如inode */
- 741 }
- 742 spin_unlock(&dcache_lock);
- 743 return NULL;
- 744 }
其他的代码暂时就不看了,以后总结。。。
Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache相关推荐
- linux 目录缓冲,Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache
在文件系统中,有三大缓冲为了提升效率:inode缓冲区.dentry缓冲区.块缓冲. (内核:2.4.37) 为什么这个缓冲区会存在,不好意思,我说了废话,当然和前面一样的,为了提升效率,例如我们写一 ...
- linux 文件浏览器_浏览Linux文件系统
linux 文件浏览器 你为什么要学习? (Why would you want to learn?) Linux is probably the most used operating system ...
- linux 文件理解,linux文件系统理解
1. 文件即数据的集合,无论你有任何信息需要存储在计算机中,都要以文件的信息存在:而文件常常和具体的设备相关联,如磁盘.软盘等等. 2. 目录,即一个文件组. 3. linux支持的文件系统: Ex ...
- 论Linux文件系统
导读 本文旨在高屋建瓴地来讨论 Linux 文件系统概念,而不是对某种特定的文件系统,比如 EXT4 是如何工作的进行具体的描述.另外,本文也不是一个文件系统命令的教程. 每台通用计算机都需要将各种数 ...
- linux文件系统dentry_Linux文件系统(四)---三大缓冲区之inode缓冲区 (内存inode映像 )...
在文件系统中,有三大缓冲为了提升效率:inode缓冲区.dentry缓冲区.块缓冲. (内核:2.4.37) 一.inode缓冲区 为了加快对索引节点的索引,引入inode缓冲区,下面我们看Linux ...
- 4.2 linux文件系统-高速缓冲区
1:基本信息 代码:linux-0.11 2:高速缓冲区 高速缓冲区的管理要素 映射关系(内存和磁盘之间的映射关系) 应用程序与高速缓冲区的交互API 磁盘的交互API 高速缓冲区的管理机制(循环链表 ...
- Linux 文件系统的目录结构
1. / 文件系统的入口,最高一级目录: 2. /bin 基础系统所需要的命令位于此目录,是最小系统所需要的命令,如:ls, cp, mkdir等. 这个目录中的文件都是可执行的,一般的用户都可以使用 ...
- [ linux ] 文件系统和目录结构详解
昨天,有个小学弟了我一个linux面试题目,和她解答完之后我就想在C站开一个专栏,用于linux和windows的学习 我是这么想的,从linux入手,再写windows,最后总结常见区别 本文主要写 ...
- 简述Linux 文件系统的目录结构
转自:http://www.linuxsir.org/main/node/189 作者:北南南北 来自:LinuxSir.Org 摘要: Linux文件系统是呈树形结构,了解Linux文件系统的目录结 ...
- linux文件系统pdf_一篇文章理解Ext4文件系统的目录
使用过Linux的同学应该对Ext4文件系统都有了解.在Linux文件系统中一切皆文件,同样目录也是文件的一种类型.熟悉Linux服务器的同学经常会看到如下内容,上图是某个目录的列表内容. 在上图中每 ...
最新文章
- 人眼是具有插帧能力的
- SpringMVC框架的详细操作步骤和注解的用法
- u检验、t检验、F检验、X2检验 (转)
- 835. Trie字符串统计
- 【UVA - 11292】Dragon of Loowater (贪心,水题,模拟,twopointer双指针)
- mysql创建索引以及进程过程中出现的问题
- Python多进程实现原理
- 计算机二级数据库题库百度云,计算机二级数据库试题及答案
- esp8266教程:定时器之PWM
- 《华为研发》阅读 - 16 (矩阵式管理)
- 照片幻灯片java_Java的POI向幻灯片中插入图片算法设计
- c语言如何画出多个散点图,如何制作多参数散点图
- vue获取列表中的数量_vue.js中列表里面的子元素怎么获取列表的索引index值
- java保存时间到数据库_java new date 保存到数据库时间不对
- 打开虚拟机发现上不了网了
- 什么是MapReduce,MapReduce的工作流程和原理是什么
- (swing读书笔记)Swing Look And Feel(2)
- linux系统查看日历
- 超市收银系统服务器,超市收银系统
- IT之家,这不是个案
热门文章
- Python 面向对象编程(一)
- 各种数组元素复制方式的性能比较
- Centos7.4源码搭建zabbix3.4.11企业级监控
- 前端内容占位技术分享
- Linux基础培训笔记二
- Ext.js4 的Store携带参数加载中文,后台出现乱码解决办法
- 安全狗云备份爆笑段子~~~如果上天再给我一次机会
- Microsoft AJAX Library的beta2版发布
- 史上最全40道dubbo面试题
- 严重: Servlet.service() for servlet [taotao-manager] in context with path [] threw exception [Request