轉(zhuǎn)載于: https://blog.csdn.net/qq_34501940/article/details/51192257
dentry
dentry是一個(gè)內(nèi)存實(shí)體,其中的d_inode成員指向?qū)?yīng)的inode
struct inode * d_inode; //指向一個(gè)inode結(jié)構(gòu)。這個(gè)inode和dentry共同描述了一個(gè)普通文件或者目錄文件 struct dentry * d_parent; //父目錄的目錄項(xiàng)對(duì)象 struct list_head d_hash; //鏈接到dentry cache的hash鏈表。 struct list_head d_lru; //未使用鏈表的指針 struct list_head d_child;//dentry自身的鏈表頭,需要鏈接到父dentry的d_subdirs成員 struct list_head d_subdirs;//項(xiàng)(子項(xiàng)可能是目錄,也可能是文件)的鏈表頭,所有的子項(xiàng)都要鏈接到這個(gè)鏈表 int d_mounted;// 指示dentry是否是一個(gè)掛載點(diǎn)。如果是掛載點(diǎn),該成員不為零。 struct qstr d_name;// 成員保存的是文件或者目錄的名字。打開(kāi)一個(gè)文件的時(shí)候,根據(jù)這個(gè)成員和用戶輸入的名字比較來(lái)搜尋目標(biāo)文件
當(dāng)移動(dòng)文件的時(shí)候,需要把一個(gè)dentry結(jié)構(gòu)從舊的父dentry的鏈表上脫離,然后鏈接到新的父dentry的d_subdirs成員。這樣dentry結(jié)構(gòu)之間就構(gòu)成了一顆目錄樹(shù)
每個(gè)dentry都有一個(gè)指向其父目錄的指針(d_parent),一個(gè)子dentry的哈希列表(d_child)。其中,子dentry基本上就是目錄中的文件
dentry狀態(tài):
1.d_count=0,未使用(unused)狀態(tài),d_inode指向相關(guān)的的索引節(jié)點(diǎn)。該目錄項(xiàng)仍然包含有效的信息,只是當(dāng)前沒(méi)有人引用他。這種dentry對(duì)象在回收內(nèi)存時(shí)可能會(huì)被釋放。
2.d_count>0,正在使用(inuse)狀態(tài),d_inode指向相關(guān)的inode對(duì)象。這種dentry對(duì)象不能被釋放。
3.d_count<0,y負(fù)(negative)狀態(tài),inode對(duì)象不復(fù)存在可能被刪除,dentry對(duì)象的d_inode指針為NULL。但這種dentry對(duì)象仍然保存在dcache中,以便后續(xù)對(duì)同一文件名的查找能夠快速完成。這種dentry對(duì)象在回收內(nèi)存時(shí)將首先被釋放。
dentry與dentry_cache
dentry_cache(dcache,目錄項(xiàng)高速緩存)由兩個(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鏈表。
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)用。
inode(索引節(jié)點(diǎn))
文件儲(chǔ)存在硬盤上,硬盤的最小存儲(chǔ)單位叫做”扇區(qū)”(Sector)。每個(gè)扇區(qū)儲(chǔ)存512字節(jié)(相當(dāng)于0.5KB)。操作系統(tǒng)讀磁盤時(shí)會(huì)多個(gè)扇區(qū)組成一個(gè)塊(block)一起讀取,最常見(jiàn)大小為4kb,8個(gè)扇區(qū)組成一個(gè)塊。inode儲(chǔ)存文件的元信息,比如文件的創(chuàng)建者、文件的創(chuàng)建日期、文件的大小等。inode對(duì)應(yīng)于物理磁盤上的具體對(duì)象,一個(gè)inode可以在運(yùn)行的時(shí)候鏈接多個(gè)dentry,d_count記錄了這個(gè)鏈接的數(shù)量
__le16 i_mode; /* 文件的屬性(讀、寫、執(zhí)行權(quán)限)*/ __le16 i_uid; /* 文件擁有者的User ID */ __le32 i_size; /* 文件的字節(jié)數(shù)*/ __le32 i_atime; /* atime指文件上一次打開(kāi)的時(shí)間 */ __le32 i_ctime; /* 文件的時(shí)間戳ctime指inode上一次變動(dòng)的時(shí)間 */ __le32 i_mtime; /* mtime指文件內(nèi)容上一次變動(dòng)的時(shí)間 */ __le16 i_gid; /* 文件的Group ID*/ __le16 i_links_count; /* 鏈接數(shù),即有多少文件名指向這個(gè) __le32 i_block[EXT2_N_BLOCKS];/*文件數(shù)據(jù)block的位置*/
可以用stat命令,查看某個(gè)文件的inode信息:
stat example.txt
函數(shù)得到當(dāng)前文件或目錄的inode值后,進(jìn)入dcache查找對(duì)應(yīng)的dentry,然后順著父目錄指針d_parent得到父目錄的dentry,這樣逐級(jí)向上直到dentry= root,就得到全部目錄名稱。
inode的大小
inode會(huì)消耗硬盤空間,所以硬盤格式化的時(shí)候,操作系統(tǒng)自動(dòng)將硬盤分成兩個(gè)區(qū)域。一個(gè)是數(shù)據(jù)區(qū),存放文件數(shù)據(jù);另一個(gè)是inode區(qū)(inode table),存放inode所包含的信息。
查看每個(gè)硬盤分區(qū)的inode總數(shù)和已經(jīng)使用的數(shù)量,可以使用df命令。
df -i
sudo dumpe2fs -h /dev/hda | grep “Inode size” //查看每個(gè)inode節(jié)點(diǎn)的大小
inode號(hào)碼
每個(gè)inode都有一個(gè)號(hào)碼,操作系統(tǒng)用inode號(hào)碼來(lái)識(shí)別不同的文件。
移動(dòng)文件或重命名文件,只是改變文件名,不影響inode號(hào)碼。
打開(kāi)一個(gè)文件以后,系統(tǒng)就以inode號(hào)碼來(lái)識(shí)別這個(gè)文件,而系統(tǒng)無(wú)法從inode號(hào)碼得知文件名。
ls -i a.cpp //查看文件名對(duì)應(yīng)的inode號(hào)碼
硬鏈接就是多個(gè)文件名指向同一個(gè)inode號(hào)碼??梢杂貌煌奈募L問(wèn)同樣的內(nèi)容;對(duì)文件內(nèi)容進(jìn)行修改,會(huì)影響到所有文件名;但是,刪除一個(gè)文件名,不影響另一個(gè)文件名的訪問(wèn)。
ln 源文件 目標(biāo)文件 //創(chuàng)建硬鏈接
兩文件指向同一個(gè)inode。d_count加1。刪除一個(gè)文件名,d_count減1。當(dāng)這個(gè)值減到0,表明沒(méi)有文件名指向這個(gè)inode,系統(tǒng)就會(huì)回收這個(gè)inode號(hào)碼,以及其所對(duì)應(yīng)block區(qū)域。
創(chuàng)建目錄時(shí),默認(rèn)會(huì)生成兩個(gè)目錄項(xiàng):”.”和”..”。前者的inode號(hào)碼就是當(dāng)前目錄的inode號(hào)碼,等同于當(dāng)前目錄的”硬鏈接”;后者的inode號(hào)碼就是當(dāng)前目錄的父目錄的inode號(hào)碼,等同于父目錄的”硬鏈接”。所以,任何一個(gè)目錄的”硬鏈接”總數(shù),總是等于2加上它的子目錄總數(shù)(含隱藏目錄),這里的2是父目錄對(duì)其的“硬鏈接”和當(dāng)前目錄下的”.硬鏈接“。
軟連接就像int &a=b,雖然名字不一樣,文件A的內(nèi)容是文件B的路徑。讀取文件A時(shí),系統(tǒng)會(huì)自動(dòng)將訪問(wèn)者導(dǎo)向文件B。如果刪除了文件B,打開(kāi)文件A就會(huì)報(bào)錯(cuò)。文件A指向文件B的文件名,而不是文件B的inode號(hào)碼,文件B的inode”鏈接數(shù)”不會(huì)因此發(fā)生變化。
ln -s 源文文件或目錄 目標(biāo)文件或目錄 //創(chuàng)建軟鏈接
文件名包含特殊字符,無(wú)法正常刪除,直接刪除inode節(jié)點(diǎn),就能起到刪除文件的作用。
open文件
1、根據(jù)文件名,通過(guò)Directory里的對(duì)應(yīng)關(guān)系,找到文件對(duì)應(yīng)的Inode number
2、再根據(jù)Inode number讀取到文件的Inode table
3、再根據(jù)Inode table中的Pointer讀取到相應(yīng)的Blocks
|