dentry與inode的概念
一、dentry的定義
dentry的中文名稱是目錄項(xiàng),是Linux文件系統(tǒng)中某個(gè)索引節(jié)點(diǎn)(inode)的鏈接。這個(gè)索引節(jié)點(diǎn)可以是文件,也可以是目錄。
二、dentry的結(jié)構(gòu):以下是dentry的結(jié)構(gòu)體
struct dentry {
atomic_t d_count; 目錄項(xiàng)對(duì)象使用計(jì)數(shù)器
unsigned int d_flags; 目錄項(xiàng)標(biāo)志
struct inode * d_inode; 與文件名關(guān)聯(lián)的索引節(jié)點(diǎn)
struct dentry * d_parent; 父目錄的目錄項(xiàng)對(duì)象
struct list_head d_hash; 散列表表項(xiàng)的指針
struct list_head d_lru; 未使用鏈表的指針
struct list_head d_child; 父目錄中目錄項(xiàng)對(duì)象的鏈表的指針
struct list_head d_subdirs;對(duì)目錄而言,表示子目錄目錄項(xiàng)對(duì)象的鏈表
struct list_head d_alias; 相關(guān)索引節(jié)點(diǎn)(別名)的鏈表
int d_mounted; 對(duì)于安裝點(diǎn)而言,表示被安裝文件系統(tǒng)根項(xiàng)
struct qstr d_name; 文件名
unsigned long d_time; /* used by d_revalidate */
struct dentry_operations *d_op; 目錄項(xiàng)方法
struct super_block * d_sb; 文件的超級(jí)塊對(duì)象
vunsigned long d_vfs_flags;
void * d_fsdata;與文件系統(tǒng)相關(guān)的數(shù)據(jù)
unsigned char d_iname [DNAME_INLINE_LEN]; 存放短文件名
};
三、dentry與inode
inode(可理解為ext2 inode)對(duì)應(yīng)于物理磁盤上的具體對(duì)象,dentry是一個(gè)內(nèi)存實(shí)體,其中的d_inode成員指向?qū)?yīng)的inode。也就是說(shuō),一個(gè)inode可以在運(yùn)行的時(shí)候鏈接多個(gè)dentry,而d_count記錄了這個(gè)鏈接的數(shù)量。
按照d_count的值,dentry分為以下三種狀態(tài):
1、未使用(unused)狀態(tài):該dentry對(duì)象的引用計(jì)數(shù)d_count的值為0,但其d_inode指針仍然指向相關(guān)的的索引節(jié)點(diǎn)。該目錄項(xiàng)仍然包含有效的信息,只是當(dāng)前沒(méi)有人引用他。這種dentry對(duì)象在回收內(nèi)存時(shí)可能會(huì)被釋放。
2、正在使用(inuse)狀態(tài):處于該狀態(tài)下的dentry對(duì)象的引用計(jì)數(shù)d_count大于0,且其d_inode指向相關(guān)的inode對(duì)象。這種dentry對(duì)象不能被釋放。
3、負(fù)(negative)狀態(tài):與目錄項(xiàng)相關(guān)的inode對(duì)象不復(fù)存在(相應(yīng)的磁盤索引節(jié)點(diǎn)可能已經(jīng)被刪除),dentry對(duì)象的d_inode指針為NULL。但這種dentry對(duì)象仍然保存在dcache中,以便后續(xù)對(duì)同一文件名的查找能夠快速完成。這種dentry對(duì)象在回收內(nèi)存時(shí)將首先被釋放。
四、dentry與dentry_cache
dentry_cache簡(jiǎn)稱dcache,中文名稱是目錄項(xiàng)高速緩存,是Linux為了提高目錄項(xiàng)對(duì)象的處理效率而設(shè)計(jì)的。它主要由兩個(gè)數(shù)據(jù)結(jié)構(gòu)組成:
1、哈希鏈表dentry_hashtable:dcache中的所有dentry對(duì)象都通過(guò)d_hash指針域鏈到相應(yīng)的dentry哈希鏈表中。
2、未使用的dentry對(duì)象鏈表dentry_unused:dcache中所有處于unused狀態(tài)和negative狀態(tài)的dentry對(duì)象都通過(guò)其d_lru指針域鏈入dentry_unused鏈表中。該鏈表也稱為L(zhǎng)RU鏈表。
目錄項(xiàng)高速緩存dcache是索引節(jié)點(diǎn)緩存icache的主控器(master),也即dcache中的dentry對(duì)象控制著icache中的 inode對(duì)象的生命期轉(zhuǎn)換。無(wú)論何時(shí),只要一個(gè)目錄項(xiàng)對(duì)象存在于dcache中(非negative狀態(tài)),則相應(yīng)的inode就將總是存在,因?yàn)?inode的引用計(jì)數(shù)i_count總是大于0。當(dāng)dcache中的一個(gè)dentry被釋放時(shí),針對(duì)相應(yīng)inode對(duì)象的iput()方法就會(huì)被調(diào)用。
五、dentry_operations *d_op
struct dentry_operations {
int (*d_revalidate)(struct dentry *);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
void (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
};
d_revalidate:用于VFS使一個(gè)dentry重新生效。
d_hash:用于VFS向哈希表中加入一個(gè)dentry。
d_compare:dentry的最后一個(gè)inode被釋放時(shí)(d_count等于零),此方法被調(diào)用,因?yàn)檫@意味這沒(méi)有inode再使用此dentry;當(dāng)然,此dentry仍然有效,并且仍然在dcache中。
d_release: 用于清除一個(gè)dentry。
d_iput:用于一個(gè)dentry釋放它的inode(d_count不等于零)
六、d_parent和d_child
每個(gè)dentry都有一個(gè)指向其父目錄的指針(d_parent),一個(gè)子dentry的哈希列表(d_child)。其中,子dentry基本上就是目錄中的文件。
七、怎樣從inode值得到目錄名?
函數(shù)得到當(dāng)前文件或目錄的inode值后,進(jìn)入dcache查找對(duì)應(yīng)的dentry,然后順著父目錄指針d_parent得到父目錄的dentry,這樣逐級(jí)向上直到dentry= root,就得到全部目錄名稱。