在檔案系統中,有三大緩沖為了提升效率:inode緩沖區、dentry緩沖區、塊緩沖。
(核心:2.4.37)
為什麼這個緩沖區會存在,不好意思,我說了廢話,當然和前面一樣的,為了提升效率,例如我們寫一個.c的helloworld檔案,簡單的過程是編輯,編譯,執行。。。那麼這個過程都是需要找到所在的檔案位置的,如果每次都從根開始找并且還有構造相應的目錄項對象,是很費時的,是以将目錄項一般也都是緩存起來的~~~
Ps:dentry結構
[cpp] view plain copy print ?
- 67 struct dentry {
- 68 atomic_t d_count;
- 69 unsigned int d_flags;
- 70 struct inode * d_inode;
- 71 struct dentry * d_parent;
- 72 struct list_head d_hash;
- 73 struct list_head d_lru;
- 74 struct list_head d_child;
- 75 struct list_head d_subdirs;
- 76 struct list_head d_alias;
- 77 int d_mounted;
- 78 struct qstr d_name;
- 79 unsigned long d_time;
- 80 struct dentry_operations *d_op;
- 81 struct super_block * d_sb;
- 82 unsigned long d_vfs_flags;
- 83 void * d_fsdata;
- 84 unsigned char d_iname[DNAME_INLINE_LEN];
- 85 };
和前面的一樣,這個也涉及到幾個相應的連結清單來管理,那麼看看/fs/dcache.c中哪些連結清單被定義了。
[cpp] view plain copy print ?
- 52 static struct list_head *dentry_hashtable;
- 53 static LIST_HEAD(dentry_unused);
哈希連結清單 :從中能夠快速擷取與給定的檔案名和目錄名對應的目錄項對象。
“未使用”連結清單:所有未使用 目錄項對象都存放在一個LRU的雙向連結清單。LRU連結清單的首元素和尾元素的位址存放在變量dentry_unused中的next 域和prev域中。目錄項對象的d_lru域包含的指針指向該連結清單中相鄰目錄的對象。
簡單的看一下dcache初始化過程:
[cpp] view plain copy print ?
- 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
- 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:
[cpp] view plain copy print ?
- 580
- 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);
- 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
- 608 memcpy(str, name->name, name->len);
- 609 str[name->len] = 0;
- 610
- 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:
[cpp] view plain copy print ?
- 698
- 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);
- 715 struct list_head *tmp;
- 716
- 717 spin_lock(&dcache_lock);
- 718 tmp = head->next;
- 719 for (;;) {
- 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;
- 739 spin_unlock(&dcache_lock);
- 740 return dentry;
- 741 }
- 742 spin_unlock(&dcache_lock);
- 743 return NULL;
- 744 }
其他的代碼暫時就不看了,以後總結。。。