在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。

(内核:2.4.37)

为什么这个缓冲区会存在,不好意思,我说了废话,当然和前面一样的,为了提升效率,例如我们写一个.c的helloworld文件,简单的过程是编辑,编译,执行。。。那么这个过程都是需要找到所在的文件位置的,如果每次都从根开始找并且还有构造相应的目录项对象,是很费时的,所以将目录项一般也都是缓存起来的~~~

Ps:dentry结构

[cpp] view plaincopyprint?
  1. 67 struct dentry {
  2. 68         atomic_t d_count;
  3. 69         unsigned int d_flags;
  4. 70         struct inode  * d_inode;        /* Where the name belongs to - NULL is negative */
  5. 71         struct dentry * d_parent;       /* parent directory */
  6. 72         struct list_head d_hash;        /* lookup hash list */
  7. 73         struct list_head d_lru;         /* d_count = 0 LRU list */
  8. 74         struct list_head d_child;       /* child of parent list */
  9. 75         struct list_head d_subdirs;     /* our children */
  10. 76         struct list_head d_alias;       /* inode alias list */
  11. 77         int d_mounted;
  12. 78         struct qstr d_name;
  13. 79         unsigned long d_time;           /* used by d_revalidate */
  14. 80         struct dentry_operations  *d_op;
  15. 81         struct super_block * d_sb;      /* The root of the dentry tree */
  16. 82         unsigned long d_vfs_flags;
  17. 83         void * d_fsdata;                /* fs-specific data */
  18. 84         unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
  19. 85 };

和前面的一样,这个也涉及到几个相应的链表来管理,那么看看/fs/dcache.c中哪些链表被定义了。

[cpp] view plaincopyprint?
  1. 52 static struct list_head *dentry_hashtable;
  2. 53 static LIST_HEAD(dentry_unused);

哈希链表 :从中能够快速获取与给定的文件名和目录名对应的目录项对象。

“未使用”链表:所有未使用 目录项对象都存放在一个LRU的双向链表。LRU链表的首元素和尾元素的地址存放在变量dentry_unused中的next 域和prev域中。目录项对象的d_lru域包含的指针指向该链表中相邻目录的对象。

简单的看一下dcache初始化过程:

[cpp] view plaincopyprint?
  1. 1181 static void __init dcache_init(unsigned long mempages)
  2. 1182 {
  3. 1183         struct list_head *d;
  4. 1184         unsigned long order;
  5. 1185         unsigned int nr_hash;
  6. 1186         int i;
  7. 1187
  8. 1188         /*
  9. 1189          * A constructor could be added for stable state like the lists,
  10. 1190          * but it is probably not worth it because of the cache nature
  11. 1191          * of the dcache.
  12. 1192          * If fragmentation is too bad then the SLAB_HWCACHE_ALIGN
  13. 1193          * flag could be removed here, to hint to the allocator that
  14. 1194          * it should not try to get multiple page regions.
  15. 1195          */
  16. 1196         dentry_cache = kmem_cache_create("dentry_cache",
  17. 1197                                          sizeof(struct dentry),
  18. 1198                                          0,
  19. 1199                                          SLAB_HWCACHE_ALIGN,
  20. 1200                                          NULL, NULL);
  21. 1201         if (!dentry_cache)
  22. 1202                 panic("Cannot create dentry cache");
  23. 1203
  24. 1204 #if PAGE_SHIFT < 13
  25. 1205         mempages >>= (13 - PAGE_SHIFT);
  26. 1206 #endif
  27. 1207         mempages *= sizeof(struct list_head);
  28. 1208         for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
  29. 1209                 ;
  30. 1210
  31. 1211         do {
  32. 1212                 unsigned long tmp;
  33. 1213
  34. 1214                 nr_hash = (1UL << order) * PAGE_SIZE /
  35. 1215                         sizeof(struct list_head);
  36. 1216                 d_hash_mask = (nr_hash - 1);
  37. 1217
  38. 1218                 tmp = nr_hash;
  39. 1219                 d_hash_shift = 0;
  40. 1220                 while ((tmp >>= 1UL) != 0UL)
  41. 1221                         d_hash_shift++;
  42. 1222
  43. 1223                 dentry_hashtable = (struct list_head *)
  44. 1224                         __get_free_pages(GFP_ATOMIC, order);
  45. 1225         } while (dentry_hashtable == NULL && --order >= 0);
  46. 1226
  47. 1227         printk(KERN_INFO "Dentry cache hash table entries: %d (order: %ld, %ld bytes)\n",
  48. 1228                         nr_hash, order, (PAGE_SIZE << order));
  49. 1229
  50. 1230         if (!dentry_hashtable)
  51. 1231                 panic("Failed to allocate dcache hash table\n");
  52. 1232
  53. 1233         d = dentry_hashtable;
  54. 1234         i = nr_hash;
  55. 1235         do {
  56. 1236                 INIT_LIST_HEAD(d);
  57. 1237                 d++;
  58. 1238                 i--;
  59. 1239         } while (i);
  60. 1240 }

上面代码就是相当于分配cache空间,并将hash表什么的都初始化了~~~

下面看一下怎么分配一个目录项对象,涉及函数d_alloc:

[cpp] view plaincopyprint?
  1. 580 /**
  2. 581  * d_alloc      -       allocate a dcache entry
  3. 582  * @parent: parent of entry to allocate
  4. 583  * @name: qstr of the name
  5. 584  *
  6. 585  * Allocates a dentry. It returns %NULL if there is insufficient memory
  7. 586  * available. On a success the dentry is returned. The name passed in is
  8. 587  * copied and the copy passed in may be reused after this call.
  9. 588  */
  10. 589
  11. 590 struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
  12. 591 {
  13. 592         char * str;
  14. 593         struct dentry *dentry;
  15. 594
  16. 595         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);   /* 分配一个dentry空间 */
  17. 596         if (!dentry)
  18. 597                 return NULL;
  19. 598
  20. 599         if (name->len > DNAME_INLINE_LEN-1) {
  21. 600                 str = kmalloc(NAME_ALLOC_LEN(name->len), GFP_KERNEL);
  22. 601                 if (!str) {
  23. 602                         kmem_cache_free(dentry_cache, dentry);
  24. 603                         return NULL;
  25. 604                 }
  26. 605         } else
  27. 606                 str = dentry->d_iname;
  28. 607         /* 复制name */
  29. 608         memcpy(str, name->name, name->len);
  30. 609         str[name->len] = 0;
  31. 610         /* 下面根据dentr的字段进行赋值,具体的字段意义见:http://blog.csdn.net/shanshanpt/article/details/38943731 */
  32. 611         atomic_set(&dentry->d_count, 1);
  33. 612         dentry->d_vfs_flags = 0;
  34. 613         dentry->d_flags = 0;
  35. 614         dentry->d_inode = NULL;
  36. 615         dentry->d_parent = NULL;
  37. 616         dentry->d_sb = NULL;
  38. 617         dentry->d_name.name = str;
  39. 618         dentry->d_name.len = name->len;
  40. 619         dentry->d_name.hash = name->hash;
  41. 620         dentry->d_op = NULL;
  42. 621         dentry->d_fsdata = NULL;
  43. 622         dentry->d_mounted = 0;
  44. 623         INIT_LIST_HEAD(&dentry->d_hash);
  45. 624         INIT_LIST_HEAD(&dentry->d_lru);
  46. 625         INIT_LIST_HEAD(&dentry->d_subdirs);
  47. 626         INIT_LIST_HEAD(&dentry->d_alias);
  48. 627         if (parent) {
  49. 628                 dentry->d_parent = dget(parent);
  50. 629                 dentry->d_sb = parent->d_sb;
  51. 630         } else
  52. 631                 INIT_LIST_HEAD(&dentry->d_child);
  53. 632
  54. 633         spin_lock(&dcache_lock);
  55. 634         if (parent)
  56. 635                 list_add(&dentry->d_child, &parent->d_subdirs);
  57. 636         dentry_stat.nr_dentry++;
  58. 637         spin_unlock(&dcache_lock);
  59. 638
  60. 639         return dentry;
  61. 640 }
  62. 641

下面看看怎么去寻找一个目录,涉及函数d_lookup:

[cpp] view plaincopyprint?
  1. 698 /**
  2. 699  * d_lookup - search for a dentry
  3. 700  * @parent: parent dentry
  4. 701  * @name: qstr of name we wish to find
  5. 702  *
  6. 703  * Searches the children of the parent dentry for the name in question. If
  7. 704  * the dentry is found its reference count is incremented and the dentry
  8. 705  * is returned. The caller must use d_put to free the entry when it has
  9. 706  * finished using it. %NULL is returned on failure.
  10. 707  */
  11. 708
  12. 709 struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
  13. 710 {
  14. 711         unsigned int len = name->len;
  15. 712         unsigned int hash = name->hash;
  16. 713         const unsigned char *str = name->name;
  17. 714         struct list_head *head = d_hash(parent,hash); /* 通过hash值计算得到目录项缓冲区位置的head */
  18. 715         struct list_head *tmp;
  19. 716
  20. 717         spin_lock(&dcache_lock);
  21. 718         tmp = head->next;
  22. 719         for (;;) {   /* 下面循环找到对应的dentry */
  23. 720                 struct dentry * dentry = list_entry(tmp, struct dentry, d_hash);
  24. 721                 if (tmp == head)
  25. 722                         break;
  26. 723                 tmp = tmp->next;
  27. 724                 if (dentry->d_name.hash != hash)
  28. 725                         continue;
  29. 726                 if (dentry->d_parent != parent)
  30. 727                         continue;
  31. 728                 if (parent->d_op && parent->d_op->d_compare) {
  32. 729                         if (parent->d_op->d_compare(parent, &dentry->d_name, name))
  33. 730                                 continue;
  34. 731                 } else {
  35. 732                         if (dentry->d_name.len != len)
  36. 733                                 continue;
  37. 734                         if (memcmp(dentry->d_name.name, str, len))
  38. 735                                 continue;
  39. 736                 }
  40. 737                 __dget_locked(dentry);
  41. 738                 dentry->d_vfs_flags |= DCACHE_REFERENCED;   /* 找到,那么添加引用就OK */
  42. 739                 spin_unlock(&dcache_lock);
  43. 740                 return dentry;     /* 返回找到的dentry。里面有我们需要的信息例如inode */
  44. 741         }
  45. 742         spin_unlock(&dcache_lock);
  46. 743         return NULL;
  47. 744 }

其他的代码暂时就不看了,以后总结。。。

Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache相关推荐

  1. linux 目录缓冲,Linux文件系统(六)---三大缓冲区之 目录缓冲区dcache

    在文件系统中,有三大缓冲为了提升效率:inode缓冲区.dentry缓冲区.块缓冲. (内核:2.4.37) 为什么这个缓冲区会存在,不好意思,我说了废话,当然和前面一样的,为了提升效率,例如我们写一 ...

  2. linux 文件浏览器_浏览Linux文件系统

    linux 文件浏览器 你为什么要学习? (Why would you want to learn?) Linux is probably the most used operating system ...

  3. linux 文件理解,linux文件系统理解

    1.  文件即数据的集合,无论你有任何信息需要存储在计算机中,都要以文件的信息存在:而文件常常和具体的设备相关联,如磁盘.软盘等等. 2. 目录,即一个文件组. 3. linux支持的文件系统: Ex ...

  4. 论Linux文件系统

    导读 本文旨在高屋建瓴地来讨论 Linux 文件系统概念,而不是对某种特定的文件系统,比如 EXT4 是如何工作的进行具体的描述.另外,本文也不是一个文件系统命令的教程. 每台通用计算机都需要将各种数 ...

  5. linux文件系统dentry_Linux文件系统(四)---三大缓冲区之inode缓冲区 (内存inode映像 )...

    在文件系统中,有三大缓冲为了提升效率:inode缓冲区.dentry缓冲区.块缓冲. (内核:2.4.37) 一.inode缓冲区 为了加快对索引节点的索引,引入inode缓冲区,下面我们看Linux ...

  6. 4.2 linux文件系统-高速缓冲区

    1:基本信息 代码:linux-0.11 2:高速缓冲区 高速缓冲区的管理要素 映射关系(内存和磁盘之间的映射关系) 应用程序与高速缓冲区的交互API 磁盘的交互API 高速缓冲区的管理机制(循环链表 ...

  7. Linux 文件系统的目录结构

    1. / 文件系统的入口,最高一级目录: 2. /bin 基础系统所需要的命令位于此目录,是最小系统所需要的命令,如:ls, cp, mkdir等. 这个目录中的文件都是可执行的,一般的用户都可以使用 ...

  8. [ linux ] 文件系统和目录结构详解

    昨天,有个小学弟了我一个linux面试题目,和她解答完之后我就想在C站开一个专栏,用于linux和windows的学习 我是这么想的,从linux入手,再写windows,最后总结常见区别 本文主要写 ...

  9. 简述Linux 文件系统的目录结构

    转自:http://www.linuxsir.org/main/node/189 作者:北南南北 来自:LinuxSir.Org 摘要: Linux文件系统是呈树形结构,了解Linux文件系统的目录结 ...

  10. linux文件系统pdf_一篇文章理解Ext4文件系统的目录

    使用过Linux的同学应该对Ext4文件系统都有了解.在Linux文件系统中一切皆文件,同样目录也是文件的一种类型.熟悉Linux服务器的同学经常会看到如下内容,上图是某个目录的列表内容. 在上图中每 ...

最新文章

  1. 人眼是具有插帧能力的
  2. SpringMVC框架的详细操作步骤和注解的用法
  3. u检验、t检验、F检验、X2检验 (转)
  4. 835. Trie字符串统计
  5. 【UVA - 11292】Dragon of Loowater (贪心,水题,模拟,twopointer双指针)
  6. mysql创建索引以及进程过程中出现的问题
  7. Python多进程实现原理
  8. 计算机二级数据库题库百度云,计算机二级数据库试题及答案
  9. esp8266教程:定时器之PWM
  10. 《华为研发》阅读 - 16 (矩阵式管理)
  11. 照片幻灯片java_Java的POI向幻灯片中插入图片算法设计
  12. c语言如何画出多个散点图,如何制作多参数散点图
  13. vue获取列表中的数量_vue.js中列表里面的子元素怎么获取列表的索引index值
  14. java保存时间到数据库_java new date 保存到数据库时间不对
  15. 打开虚拟机发现上不了网了
  16. 什么是MapReduce,MapReduce的工作流程和原理是什么
  17. (swing读书笔记)Swing Look And Feel(2)
  18. linux系统查看日历
  19. 超市收银系统服务器,超市收银系统
  20. IT之家,这不是个案

热门文章

  1. Python 面向对象编程(一)
  2. 各种数组元素复制方式的性能比较
  3. Centos7.4源码搭建zabbix3.4.11企业级监控
  4. 前端内容占位技术分享
  5. Linux基础培训笔记二
  6. Ext.js4 的Store携带参数加载中文,后台出现乱码解决办法
  7. 安全狗云备份爆笑段子~~~如果上天再给我一次机会
  8. Microsoft AJAX Library的beta2版发布
  9. 史上最全40道dubbo面试题
  10. 严重: Servlet.service() for servlet [taotao-manager] in context with path [] threw exception [Request