這篇文章主要給大家介紹了在linux中關(guān)于inode的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
背景
最近在復(fù)習(xí)linux命令,到df的時(shí)候發(fā)現(xiàn)了一個(gè)之前忽略的東西。也就是 -i 這個(gè)選項(xiàng),列出文件系統(tǒng)分區(qū)的inode信息。這個(gè)inode,是個(gè)什么東西?
inode是用來(lái)做什么的
inode是用來(lái)存儲(chǔ)文件元信息的區(qū)域。中文譯名叫做“索引節(jié)點(diǎn)”。
關(guān)于inode的背景知識(shí)
我們先復(fù)習(xí)下文件存儲(chǔ)的一些內(nèi)容。我們知道,文件存儲(chǔ)在硬盤(pán)上,硬盤(pán)的最小存儲(chǔ)單元呢,又被稱為扇區(qū),扇區(qū)的大小是512字節(jié)。
操作系統(tǒng)在硬盤(pán)上讀取信息時(shí),是按照一次性讀取多個(gè)扇區(qū)的方式來(lái)的,而這多個(gè)扇區(qū)也叫塊。通常,塊的大小是4KB,大概有8個(gè)扇區(qū)的大小。需要注意的是,讀取的塊是連續(xù)的空間。
這個(gè)時(shí)候我們能知道,文件是存儲(chǔ)在“塊”中的,就像我們寫(xiě)C語(yǔ)言程序的時(shí)候,我們知道,當(dāng)我們聲明一個(gè)數(shù)組的時(shí)候,不僅僅會(huì)存儲(chǔ)放在數(shù)組里面的值,還會(huì)存儲(chǔ)對(duì)應(yīng)的數(shù)組信息,比如數(shù)組的首地址、文件類型和數(shù)組長(zhǎng)度等等,同樣的,需要找一個(gè)地方存儲(chǔ)文件的元信息,類似于文件的創(chuàng)建相關(guān)的信息、文件的長(zhǎng)度等等。而這個(gè)地方,我們稱做inode。
inode中存儲(chǔ)的內(nèi)容
inode包含著所存儲(chǔ)文件的元信息,包含著這些內(nèi)容:
-
文件的字節(jié)數(shù)。
-
文件創(chuàng)建者的ID。
-
文件的Group ID。
-
文件的讀寫(xiě)等權(quán)限。
-
文件的相關(guān)時(shí)間戳。具體的有三個(gè):ctime–>inode上一次變動(dòng)的時(shí)間;mtime–>文件內(nèi)容上一次變動(dòng)的時(shí)間;atime–>文件上一次打開(kāi)的時(shí)間。
-
鏈接數(shù)
-
文件數(shù)據(jù)的塊位置
inode號(hào)碼
第一次看到上面的存儲(chǔ)內(nèi)容后,我想大家多少會(huì)有相同的疑問(wèn),既然inode是存儲(chǔ)文件相關(guān)信息的,為什么不存儲(chǔ)文件名呢。理由就是,文件名并不是Unix/Linux操作系統(tǒng)識(shí)別不同文件的標(biāo)準(zhǔn)。
操作系統(tǒng)是通過(guò)inode號(hào)碼來(lái)識(shí)別不同文件的。
在Unix/Linux系統(tǒng)中,用戶層名是通過(guò)文件名來(lái)打開(kāi)文件的,系統(tǒng)層面主要是通過(guò)了三個(gè)步驟來(lái)打開(kāi)文件:
-
根據(jù)文件名找到對(duì)應(yīng)的inode號(hào)碼。
-
通過(guò)inode號(hào)碼獲取inode信息。
-
根據(jù)inode信息,找到文件數(shù)據(jù)所存的塊,并獨(dú)處數(shù)據(jù)。
inode的特殊作用
Unix/Linux系統(tǒng)中inode號(hào)碼和文件名分離,這導(dǎo)致了系統(tǒng)中一些特別的現(xiàn)象:
-
刪除inode節(jié)點(diǎn),即是刪除文件。有些文件可能無(wú)法正確刪除,這時(shí)我們直接刪掉對(duì)應(yīng)的inode節(jié)點(diǎn),就可以起到刪除文件的作用。
-
移動(dòng)文件或者重命名文件,不改變inode號(hào)碼,僅僅只是改變文件名。
-
通常來(lái)說(shuō),系統(tǒng)是無(wú)法通過(guò)inode號(hào)碼得到文件名的,當(dāng)打開(kāi)一個(gè)文件,系統(tǒng)往后就通過(guò)inode來(lái)識(shí)別該文件,不再考慮文件名。
因?yàn)閕node號(hào)碼的存在,系統(tǒng)可以在軟件不關(guān)閉的情況下進(jìn)行更新。系統(tǒng)通過(guò)inode號(hào)碼,識(shí)別運(yùn)行中的文件,更新過(guò)程中,文件以相同的文件名,新的inode存在,而不會(huì)影響到目前運(yùn)行中的文件。而原先舊版的inode會(huì)在軟件下一次打開(kāi)時(shí)被回收,文件名會(huì)自動(dòng)指向新的inode號(hào)碼。
inode空間占用問(wèn)題
既然同樣是存儲(chǔ)在硬盤(pán)里的數(shù)據(jù),inode必然也是會(huì)占用硬盤(pán)空間的,當(dāng)格式化硬盤(pán)的時(shí)候,操作系統(tǒng)會(huì)自動(dòng)將硬盤(pán)分成兩個(gè)區(qū)域:
-
數(shù)據(jù)區(qū)
-
inode table
數(shù)據(jù)區(qū)主要存放文件數(shù)據(jù),inode table區(qū)域則是存放inode信息。
特別的是,inode所占用的區(qū)域大小,在磁盤(pán)格式化時(shí)操作系統(tǒng)就已經(jīng)給定。這樣做導(dǎo)致的后果就是,數(shù)據(jù)區(qū)的空間明明還沒(méi)有使用完,但是卻無(wú)法繼續(xù)存取數(shù)據(jù)了,這時(shí)因?yàn)閕node table區(qū)域已經(jīng)用滿了,所以無(wú)法再往磁盤(pán)里存儲(chǔ)新的文件。
目錄文件
我們知道,在Unix/Linux中,任何資源都是以文件的形式存在的。目錄也是。我們打開(kāi)目錄,實(shí)際上就是打開(kāi)目錄文件。目錄文件的結(jié)構(gòu)就是一個(gè)列表。
目錄項(xiàng) = 所包含文件文件名 + 對(duì)應(yīng)inode號(hào)碼。
硬鏈接和軟鏈接
關(guān)于具體什么是硬鏈接什么是軟鏈接,我就不在這篇博文里贅述了,僅從inode角度去考慮。
從inode號(hào)碼的角度考慮,Unix/Linux系統(tǒng)中,是允許多個(gè)文件名指向同一個(gè)inode號(hào)碼的。這個(gè)時(shí)候,如果刪除掉其中一個(gè)文件名,不影響另一個(gè)文件名的訪問(wèn),同時(shí),如果通過(guò)一個(gè)文件名打開(kāi)文件并作出修改,其他文件名打開(kāi)時(shí)可以共享到該修改。那么就稱這種為“硬鏈接”。在Linux中,我們可以通過(guò)ln命令來(lái)創(chuàng)建硬鏈接。
上面總結(jié)到,在inode中,有一個(gè)存儲(chǔ)項(xiàng)叫做“鏈接數(shù)”,記錄只想該inode的文件名總數(shù)。如果通過(guò)硬鏈接方式創(chuàng)建一個(gè)文件名指向某文件,那該文件對(duì)應(yīng)的inode數(shù)據(jù)域中鏈接數(shù)部分就會(huì) + 1,反之 – 1 。當(dāng)這個(gè)值為0時(shí),系統(tǒng)就會(huì)默認(rèn)沒(méi)有文件名指向該inode,此時(shí),就會(huì)回收該inode號(hào)碼,并且回收對(duì)應(yīng)的塊區(qū)域。
而對(duì)應(yīng)的軟鏈接,假設(shè)有文件A和文件B,B是A的軟鏈接。這個(gè)時(shí)候,A和B的inode號(hào)碼是不同的,因?yàn)樗鼈兪遣煌奈募牵的內(nèi)容是A的路徑,讀取B的時(shí)候,系統(tǒng)會(huì)自動(dòng)訪問(wèn)A,所以無(wú)論打開(kāi)哪個(gè)文件,訪問(wèn)的都是文件A。這個(gè)時(shí)候,文件B就被稱為文件A的“軟鏈接”或者“符號(hào)鏈接”。
在Unix/Linux系統(tǒng)中,我們可以通過(guò)ln -s 命令來(lái)創(chuàng)建軟鏈接。
總結(jié)和小補(bǔ)充
通過(guò)上面的敘述,我們知道inode就像C語(yǔ)言中的指針域,指針域記錄著多種信息,并把我們導(dǎo)向正確的文件位置,讀取需要的信息。(當(dāng)然也不是完全像。)
Unix/Linux系統(tǒng)中創(chuàng)建目錄時(shí),會(huì)自動(dòng)生成兩個(gè)目錄項(xiàng):
-
.目錄
-
..目錄
可以通過(guò) ls -al 命令觀察到這兩個(gè)目錄。“.目錄“的inode號(hào)碼是當(dāng)前目錄的inode號(hào)碼,等同于當(dāng)前目錄的硬鏈接,而“..“目錄的inode號(hào)碼是當(dāng)前目錄父目錄的inode號(hào)碼,等同于父目錄的硬鏈接。目錄硬鏈接總數(shù) = 2 + 子目錄總數(shù)(包括隱藏文件)。