目錄項快取記憶體
快取狀態
快取管理
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
* 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);