新聞中心
文章有些長(zhǎng),但是作者總結(jié)的非常好,能學(xué)到很多技術(shù)細(xì)節(jié)知識(shí)。請(qǐng)大家耐心閱讀。

專(zhuān)注于為中小企業(yè)提供網(wǎng)站制作、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)富蘊(yùn)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千多家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
將磁盤(pán)進(jìn)行分區(qū),分區(qū)是將磁盤(pán)按柱面進(jìn)行物理上的劃分。劃分好分區(qū)后還要進(jìn)行格式化,然后再掛載才能使用(不考慮其他方法)。格式化分區(qū)的過(guò)程其實(shí)就是創(chuàng)建文件系統(tǒng)。
文件系統(tǒng)的類(lèi)型有很多種,如CentOS 5和CentOS 6上默認(rèn)使用的ext2/ext3/ext4,CentOS 7上默認(rèn)使用的xfs,windows上的NTFS,光盤(pán)類(lèi)的文件系統(tǒng)ISO9660,MAC上的混合文件系統(tǒng)HFS,網(wǎng)絡(luò)文件系統(tǒng)NFS,Oracle研發(fā)的btrfs,還有老式的FAT/FAT32等。
本文將非常全面且詳細(xì)地介紹ext家族的文件系統(tǒng),中間還非常詳細(xì)地介紹了inode、軟鏈接、硬鏈接、數(shù)據(jù)存儲(chǔ)方式以及操作文件的理論,基本上看完本文,對(duì)文件系統(tǒng)的宏觀理解將再無(wú)疑惑。ext家族的文件系統(tǒng)有ext2/ext3/ext4,ext3是有日志的ext2改進(jìn)版,ext4對(duì)相比ext3做了非常多的改進(jìn)。雖然xfs/btrfs等文件系統(tǒng)有所不同,但它們只是在實(shí)現(xiàn)方式上不太同,再加上屬于自己的特性而已。
1.文件系統(tǒng)的組成部分
1.1 block的出現(xiàn)
硬盤(pán)最底層的讀寫(xiě)IO一次是一個(gè)扇區(qū)512字節(jié),如果要讀寫(xiě)大量文件,以扇區(qū)為單位肯定很慢很消耗性能,所以硬盤(pán)使用了一個(gè)稱(chēng)作邏輯塊的概念。邏輯塊是邏輯的,由磁盤(pán)驅(qū)動(dòng)器負(fù)責(zé)維護(hù)和操作,它并非是像扇區(qū)一樣物理劃分的。一個(gè)邏輯塊的大小可能包含一個(gè)或多個(gè)扇區(qū),每個(gè)邏輯塊都有唯一的地址,稱(chēng)為L(zhǎng)BA。有了邏輯塊之后,磁盤(pán)控制器對(duì)數(shù)據(jù)的操作就以邏輯塊為單位,一次讀寫(xiě)一個(gè)邏輯塊,磁盤(pán)控制器知道如何將邏輯塊翻譯成對(duì)應(yīng)的扇區(qū)并讀寫(xiě)數(shù)據(jù)。
到了Linux操作系統(tǒng)層次,通過(guò)文件系統(tǒng)提供了一個(gè)也稱(chēng)為塊的讀寫(xiě)單元,文件系統(tǒng)數(shù)據(jù)塊的大小一般為1024bytes(1K)或2048bytes(2K)或4096bytes(4K)。文件系統(tǒng)數(shù)據(jù)塊也是邏輯概念,是文件系統(tǒng)層次維護(hù)的,而磁盤(pán)上的邏輯數(shù)據(jù)塊是由磁盤(pán)控制器維護(hù)的,文件系統(tǒng)的IO管理器知道如何將它的數(shù)據(jù)塊翻譯成磁盤(pán)維護(hù)的數(shù)據(jù)塊地址LBA。對(duì)于使用文件系統(tǒng)的IO操作來(lái)說(shuō),比如讀寫(xiě)文件,這些IO的基本單元是文件系統(tǒng)上的數(shù)據(jù)塊,一次讀寫(xiě)一個(gè)文件系統(tǒng)數(shù)據(jù)塊。比如需要讀一個(gè)或多個(gè)塊時(shí),文件系統(tǒng)的IO管理器首先計(jì)算這些文件系統(tǒng)塊對(duì)應(yīng)在哪些磁盤(pán)數(shù)據(jù)塊,也就是計(jì)算出LBA,然后通知磁盤(pán)控制器要讀取哪些塊的數(shù)據(jù),硬盤(pán)控制器將這些塊翻譯成扇區(qū)地址,然后從扇區(qū)中讀取數(shù)據(jù),再通過(guò)硬盤(pán)控制器將這些扇區(qū)數(shù)據(jù)重組寫(xiě)入到內(nèi)存中去。
本文既然是討論文件系統(tǒng)的,那么重點(diǎn)自然是在文件系統(tǒng)上而不是在磁盤(pán)上,所以后文出現(xiàn)的block均表示的是文件系統(tǒng)的數(shù)據(jù)塊而不是磁盤(pán)維護(hù)的邏輯塊。
文件系統(tǒng)block的出現(xiàn)使得在文件系統(tǒng)層面上讀寫(xiě)性能大大提高,也大量減少了碎片。但是它的副作用是可能造成空間浪費(fèi)。由于文件系統(tǒng)以block為讀寫(xiě)單元,即使存儲(chǔ)的文件只有1K大小也將占用一個(gè)block,剩余的空間完全是浪費(fèi)的。在某些業(yè)務(wù)需求下可能大量存儲(chǔ)小文件,這會(huì)浪費(fèi)大量的空間。
盡管有缺點(diǎn),但是其優(yōu)點(diǎn)足夠明顯,在當(dāng)下硬盤(pán)容量廉價(jià)且追求性能的時(shí)代,使用block是一定的。
1.2 inode的出現(xiàn)
如果存儲(chǔ)的1個(gè)文件占用了大量的block讀取時(shí)會(huì)如何?假如block大小為1KB,僅僅存儲(chǔ)一個(gè)10M的文件就需要10240個(gè)block,而且這些blocks很可能在位置上是不連續(xù)在一起的(不相鄰),讀取該文件時(shí)難道要從前向后掃描整個(gè)文件系統(tǒng)的塊,然后找出屬于該文件的塊嗎?顯然是不應(yīng)該這么做的,因?yàn)樘倒鲜搅?。再考慮一下,讀取一個(gè)只占用1個(gè)block的文件,難道只讀取一個(gè)block就結(jié)束了嗎?并不是,仍然是掃描整個(gè)文件系統(tǒng)的所有block,因?yàn)樗恢朗裁磿r(shí)候掃描到,掃描到了它也不知道這個(gè)文件是不是已經(jīng)完整而不需要再掃描其他的block。
另外,每個(gè)文件都有屬性(如權(quán)限、大小、時(shí)間戳等),這些屬性類(lèi)的元數(shù)據(jù)存儲(chǔ)在哪里呢?難道也和文件的數(shù)據(jù)部分存儲(chǔ)在塊中嗎?如果一個(gè)文件占用多個(gè)block那是不是每個(gè)屬于該文件的block都要存儲(chǔ)一份文件元數(shù)據(jù)?但是如果不在每個(gè)block中存儲(chǔ)元數(shù)據(jù)文件系統(tǒng)又怎么知道某一個(gè)block是不是屬于該文件呢?但是顯然,每個(gè)數(shù)據(jù)block中都存儲(chǔ)一份元數(shù)據(jù)太浪費(fèi)空間。
文件系統(tǒng)設(shè)計(jì)者當(dāng)然知道這樣的存儲(chǔ)方式很不理想,所以需要優(yōu)化存儲(chǔ)方式。如何優(yōu)化?對(duì)于這種類(lèi)似的問(wèn)題的解決方法是使用索引,通過(guò)掃描索引找到對(duì)應(yīng)的數(shù)據(jù),而且索引可以存儲(chǔ)部分?jǐn)?shù)據(jù)。
在文件系統(tǒng)上索引技術(shù)具體化為索引節(jié)點(diǎn)(index node),在索引節(jié)點(diǎn)上存儲(chǔ)的部分?jǐn)?shù)據(jù)即為文件的屬性元數(shù)據(jù)及其他少量信息。一般來(lái)說(shuō)索引占用的空間相比其索引的文件數(shù)據(jù)而言占用的空間就小得多,掃描它比掃描整個(gè)數(shù)據(jù)要快得多,否則索引就沒(méi)有存在的意義。這樣一來(lái)就解決了前面所有的問(wèn)題。
在文件系統(tǒng)上的術(shù)語(yǔ)中,索引節(jié)點(diǎn)稱(chēng)為inode。在inode中存儲(chǔ)了inode號(hào)、文件類(lèi)型、權(quán)限、文件所有者、大小、時(shí)間戳等元數(shù)據(jù)信息,最重要的是還存儲(chǔ)了指向?qū)儆谠撐募lock的指針,這樣讀取inode就可以找到屬于該文件的block,進(jìn)而讀取這些block并獲得該文件的數(shù)據(jù)。由于后面還會(huì)介紹一種指針,為了方便稱(chēng)呼和區(qū)分,暫且將這個(gè)inode記錄中指向文件data block的指針?lè)Q之為block指針。以下是ext2文件系統(tǒng)中inode包含的信息示例:
- Inode: 12 Type: regular Mode: 0644 Flags: 0x0
- Generation: 1454951771 Version: 0x00000000:00000001
- User: 0 Group: 0 Size: 5
- File ACL: 0 Directory ACL: 0
- Links: 1 Blockcount: 8
- Fragment: Address: 0 Number: 0 Size: 0
- ctime: 0x5b628db2:15e0aff4 -- Thu Aug 2 12:50:58 2018
- atime: 0x5b628db2:15e0aff4 -- Thu Aug 2 12:50:58 2018
- mtime: 0x5b628db2:15e0aff4 -- Thu Aug 2 12:50:58 2018
- crtime: 0x5b628db2:15e0aff4 -- Thu Aug 2 12:50:58 2018
- Size of extra inode fields: 28
- BLOCKS:
- (0):1024
- TOTAL: 1
一般inode大小為128字節(jié)或256字節(jié),相比那些MB或GB計(jì)算的文件數(shù)據(jù)而言小得多的多,但也要知道可能一個(gè)文件大小小于inode大小,例如只占用1個(gè)字節(jié)的文件。
1.3 bmap出現(xiàn)
在向硬盤(pán)存儲(chǔ)數(shù)據(jù)時(shí),文件系統(tǒng)需要知道哪些塊是空閑的,哪些塊是已經(jīng)占用了的。最笨的方法當(dāng)然是從前向后掃描,遇到空閑塊就存儲(chǔ)一部分,繼續(xù)掃描直到存儲(chǔ)完所有數(shù)據(jù)。
優(yōu)化的方法當(dāng)然也可以考慮使用索引,但是僅僅1G的文件系統(tǒng)就有1KB的block共1024*1024=1048576個(gè),這僅僅只是1G,如果是100G、500G甚至更大呢,僅僅使用索引索引的數(shù)量和空間占用也將極大,這時(shí)就出現(xiàn)更高一級(jí)的優(yōu)化方法:使用塊位圖(bitmap簡(jiǎn)稱(chēng)bmap)。
位圖只使用0和1標(biāo)識(shí)對(duì)應(yīng)block是空閑還是被占用,0和1在位圖中的位置和block的位置一一對(duì)應(yīng),第一位標(biāo)識(shí)第一個(gè)塊,第二個(gè)位標(biāo)識(shí)第二個(gè)塊,依次下去直到標(biāo)記完所有的block。
考慮下為什么塊位圖更優(yōu)化。在位圖中1個(gè)字節(jié)8個(gè)位,可以標(biāo)識(shí)8個(gè)block。對(duì)于一個(gè)block大小為1KB、容量為1G的文件系統(tǒng)而言,block數(shù)量有1024*1024個(gè),所以在位圖中使用1024*1024個(gè)位共1024*1024/8=131072字節(jié)=128K,即1G的文件只需要128個(gè)block做位圖就能完成一一對(duì)應(yīng)。通過(guò)掃描這100多個(gè)block就能知道哪些block是空閑的,速度提高了非常多。
但是要注意,bmap的優(yōu)化針對(duì)的是寫(xiě)優(yōu)化,因?yàn)橹挥袑?xiě)才需要找到空閑block并分配空閑block。對(duì)于讀而言,只要通過(guò)inode找到了block的位置,cpu就能迅速計(jì)算出block在物理磁盤(pán)上的地址,cpu的計(jì)算速度是極快的,計(jì)算block地址的時(shí)間幾乎可以忽略,那么讀速度基本認(rèn)為是受硬盤(pán)本身性能的影響而與文件系統(tǒng)無(wú)關(guān)。大多數(shù)稍大一點(diǎn)的文件可能都會(huì)存儲(chǔ)在不連續(xù)的block上,而且使用了一段時(shí)間的文件系統(tǒng)可能會(huì)有不少碎片,這時(shí)硬盤(pán)的隨機(jī)讀取性能直接決定讀數(shù)據(jù)的速度,這也是機(jī)械硬盤(pán)速度相比固態(tài)硬盤(pán)慢的多的多的原因之一,而且固態(tài)硬盤(pán)的隨機(jī)讀和連續(xù)讀取速度幾乎是一致的,對(duì)它來(lái)說(shuō),文件系統(tǒng)碎片的多少并不會(huì)影響讀取速度。
雖然bmap已經(jīng)極大的優(yōu)化了掃描,但是仍有其瓶頸:如果文件系統(tǒng)是100G呢?100G的文件系統(tǒng)要使用128*100=12800個(gè)1KB大小的block,這就占用了12.5M的空間了。試想完全掃描12800個(gè)很可能不連續(xù)的block這也是需要占用一些時(shí)間的,雖然快但是扛不住每次存儲(chǔ)文件都要掃描帶來(lái)的巨大開(kāi)銷(xiāo)。
所以需要再次優(yōu)化,如何優(yōu)化?簡(jiǎn)而言之就是將文件系統(tǒng)劃分開(kāi)形成塊組,至于塊組的介紹放在后文。
1.4 inode表的出現(xiàn)
回顧下inode相關(guān)信息:inode存儲(chǔ)了inode號(hào)、文件屬性元數(shù)據(jù)、指向文件占用的block的指針;每一個(gè)inode占用128字節(jié)或256字節(jié)。
現(xiàn)在又出現(xiàn)問(wèn)題了,一個(gè)文件系統(tǒng)中可以說(shuō)有無(wú)數(shù)多個(gè)文件,每一個(gè)文件都對(duì)應(yīng)一個(gè)inode,難道每一個(gè)僅128字節(jié)的inode都要單獨(dú)占用一個(gè)block進(jìn)行存儲(chǔ)嗎?這太浪費(fèi)空間了。
所以更優(yōu)的方法是將多個(gè)inode合并存儲(chǔ)在block中,對(duì)于128字節(jié)的inode,一個(gè)block存儲(chǔ)8個(gè)inode,對(duì)于256字節(jié)的inode,一個(gè)block存儲(chǔ)4個(gè)inode。這就使得每個(gè)存儲(chǔ)inode的塊都不浪費(fèi)。
在ext文件系統(tǒng)上,將這些物理上存儲(chǔ)inode的block組合起來(lái),在邏輯上形成一張inode表(inode table)來(lái)記錄所有的inode。
舉個(gè)例子,每一個(gè)家庭都要向派出所登記戶口信息,通過(guò)戶口本可以知道家庭住址,而每個(gè)鎮(zhèn)或街道的派出所將本鎮(zhèn)或本街道的所有戶口整合在一起,要查找某一戶地址時(shí),在派出所就能快速查找到。inode table就是這里的派出所。它的內(nèi)容如下圖所示。
實(shí)際上,在文件系統(tǒng)創(chuàng)建完成后所有的inode號(hào)都已經(jīng)分配好并記錄到inode table中了,只不過(guò)被使用的inode號(hào)所在的行還有文件屬性的元數(shù)據(jù)信息和block位置信息,而未被使用的inode號(hào)只有一個(gè)inode號(hào)而已而沒(méi)有其他信息而已。
再細(xì)細(xì)一思考,就能發(fā)現(xiàn)一個(gè)大的文件系統(tǒng)仍將占用大量的塊來(lái)存儲(chǔ)inode,想要找到其中的一個(gè)inode記錄也需要不小的開(kāi)銷(xiāo),盡管它們已經(jīng)形成了一張邏輯上的表,但扛不住表太大記錄太多。那么如何快速找到inode,這同樣是需要優(yōu)化的,優(yōu)化的方法是將文件系統(tǒng)的block進(jìn)行分組劃分,每個(gè)組中都存有本組inode table范圍、bmap等。
1.5 imap的出現(xiàn)
前面說(shuō)bmap是塊位圖,用于標(biāo)識(shí)文件系統(tǒng)中哪些block是空閑哪些block是占用的。
對(duì)于inode也一樣,在存儲(chǔ)文件(Linux中一切皆文件)時(shí)需要為其分配一個(gè)inode號(hào)。但是在格式化創(chuàng)建文件系統(tǒng)后所有的inode號(hào)都是被事先設(shè)定好存放在inode table中的,因此產(chǎn)生了問(wèn)題:要為文件分配哪一個(gè)inode號(hào)呢?又如何知道某一個(gè)inode號(hào)是否已經(jīng)被分配了呢?
既然是"是否被占用"的問(wèn)題,使用位圖是最佳方案,像bmap記錄block的占用情況一樣。標(biāo)識(shí)inode號(hào)是否被分配的位圖稱(chēng)為inodemap簡(jiǎn)稱(chēng)為imap。這時(shí)要為一個(gè)文件分配inode號(hào)只需掃描imap即可知道哪一個(gè)inode號(hào)是空閑的。
imap存在著和bmap和inode table一樣需要解決的問(wèn)題:如果文件系統(tǒng)比較大,imap本身就會(huì)很大,每次存儲(chǔ)文件都要進(jìn)行掃描,會(huì)導(dǎo)致效率不夠高。同樣,優(yōu)化的方式是將文件系統(tǒng)占用的block劃分成塊組,每個(gè)塊組有自己的imap范圍。
1.6 塊組的出現(xiàn)
前面一直提到的優(yōu)化方法是將文件系統(tǒng)占用的block劃分成塊組(block group),解決bmap、inode table和imap太大的問(wèn)題。
在物理層面上的劃分是將磁盤(pán)按柱面劃分為多個(gè)分區(qū),即多個(gè)文件系統(tǒng);在邏輯層面上的劃分是將文件系統(tǒng)劃分成塊組。每個(gè)文件系統(tǒng)包含多個(gè)塊組,每個(gè)塊組包含多個(gè)元數(shù)據(jù)區(qū)和數(shù)據(jù)區(qū):元數(shù)據(jù)區(qū)就是存儲(chǔ)bmap、inode table、imap等的數(shù)據(jù);數(shù)據(jù)區(qū)就是存儲(chǔ)文件數(shù)據(jù)的區(qū)域。注意塊組是邏輯層面的概念,所以并不會(huì)真的在磁盤(pán)上按柱面、按扇區(qū)、按磁道等概念進(jìn)行劃分。
1.7 塊組的劃分
塊組在文件系統(tǒng)創(chuàng)建完成后就已經(jīng)劃分完成了,也就是說(shuō)元數(shù)據(jù)區(qū)bmap、inode table和imap等信息占用的block以及數(shù)據(jù)區(qū)占用的block都已經(jīng)劃分好了。那么文件系統(tǒng)如何知道一個(gè)塊組元數(shù)據(jù)區(qū)包含多少個(gè)block,數(shù)據(jù)區(qū)又包含多少block呢?
它只需確定一個(gè)數(shù)據(jù)——每個(gè)block的大小,再根據(jù)bmap至多只能占用一個(gè)完整的block的標(biāo)準(zhǔn)就能計(jì)算出塊組如何劃分。如果文件系統(tǒng)非常小,所有的bmap總共都不能占用完一個(gè)block,那么也只能空閑bmap的block了。
每個(gè)block的大小在創(chuàng)建文件系統(tǒng)時(shí)可以人為指定,不指定也有默認(rèn)值。
假如現(xiàn)在block的大小是1KB,一個(gè)bmap完整占用一個(gè)block能標(biāo)識(shí)1024*8= 8192個(gè)block(當(dāng)然這8192個(gè)block是數(shù)據(jù)區(qū)和元數(shù)據(jù)區(qū)共8192個(gè),因?yàn)樵獢?shù)據(jù)區(qū)分配的block也需要通過(guò)bmap來(lái)標(biāo)識(shí))。每個(gè)block是1K,每個(gè)塊組是8192K即8M,創(chuàng)建1G的文件系統(tǒng)需要?jiǎng)澐?024/8=128個(gè)塊組,如果是1.1G的文件系統(tǒng)呢?128+12.8=128+13=141個(gè)塊組。
每個(gè)組的block數(shù)目是劃分好了,但是每個(gè)組設(shè)定多少個(gè)inode號(hào)呢?inode table占用多少block呢?這需要由系統(tǒng)決定了,因?yàn)槊枋?每多少個(gè)數(shù)據(jù)區(qū)的block就為其分配一個(gè)inode號(hào)"的指標(biāo)默認(rèn)是我們不知道的,當(dāng)然創(chuàng)建文件系統(tǒng)時(shí)也可以人為指定這個(gè)指標(biāo)或者百分比例。見(jiàn)后文"inode深入"。
使用dumpe2fs可以將ext類(lèi)的文件系統(tǒng)信息全部顯示出來(lái),當(dāng)然bmap是每個(gè)塊組固定一個(gè)block的不用顯示,imap比bmap更小所以也只占用1個(gè)block不用顯示。
下圖是一個(gè)文件系統(tǒng)的部分信息,在這些信息的后面還有每個(gè)塊組的信息,其實(shí)這里面的很多信息都可以通過(guò)幾個(gè)比較基本的元數(shù)據(jù)推導(dǎo)出來(lái)。
從這張表中能計(jì)算出文件系統(tǒng)的大小,該文件系統(tǒng)共4667136個(gè)blocks,每個(gè)block大小為4K,所以文件系統(tǒng)大小為4667136*4/1024/1024=17.8GB。
也能計(jì)算出分了多少個(gè)塊組,因?yàn)槊恳粋€(gè)塊組的block數(shù)量為32768,所以塊組的數(shù)量為4667136/32768=142.4即143個(gè)塊組。由于塊組從0開(kāi)始編號(hào),所以最后一個(gè)塊組編號(hào)為Group 142。如下圖所示是最后一個(gè)塊組的信息。
2. 文件系統(tǒng)的完整結(jié)構(gòu)
將上文描述的bmap、inode table、imap、數(shù)據(jù)區(qū)的blocks和塊組的概念組合起來(lái)就形成了一個(gè)文件系統(tǒng),當(dāng)然這還不是完整的文件系統(tǒng)。完整的文件系統(tǒng)如下圖
首先,該圖中多了Boot Block、Super Block、GDT、Reserver GDT這幾個(gè)概念。下面會(huì)分別介紹它們。
然后,圖中指明了塊組中每個(gè)部分占用的block數(shù)量,除了superblock、bmap、imap能確定占用1個(gè)block,其他的部分都不能確定占用幾個(gè)block。
最后,圖中指明了Superblock、GDT和Reserved GDT是同時(shí)出現(xiàn)且不一定存在于每一個(gè)塊組中的,也指明了bmap、imap、inode table和data blocks是每個(gè)塊組都有的。
2.1 引導(dǎo)塊
即上圖中的Boot Block部分,也稱(chēng)為boot sector。它位于分區(qū)上的第一個(gè)塊,占用1024字節(jié),并非所有分區(qū)都有這個(gè)boot sector,只有裝了操作系統(tǒng)的主分區(qū)和裝了操作系統(tǒng)的邏輯分區(qū)才有。里面存放的也是boot loader,這段boot loader稱(chēng)為VBR(主分區(qū)裝操作系統(tǒng)時(shí))或EBR(擴(kuò)展分區(qū)裝操作系統(tǒng)時(shí)),這里的Boot loader和mbr上的boot loader是存在交錯(cuò)關(guān)系的。開(kāi)機(jī)啟動(dòng)的時(shí)候,首先加載mbr中的bootloader,然后定位到操作系統(tǒng)所在分區(qū)的boot serctor上加載此處的boot loader。如果是多系統(tǒng),加載mbr中的bootloader后會(huì)列出操作系統(tǒng)菜單,菜單上的各操作系統(tǒng)指向它們所在分區(qū)的boot sector上。它們之間的關(guān)系如下圖所示。
但是,這種方式的操作系統(tǒng)菜單早已經(jīng)棄之不用了,而是使用grub來(lái)管理啟動(dòng)菜單。盡管如此,在安裝操作系統(tǒng)時(shí),仍然有一步是選擇boot loader安裝位置的步驟。
2.2 超級(jí)塊(superblock)
既然一個(gè)文件系統(tǒng)會(huì)分多個(gè)塊組,那么文件系統(tǒng)怎么知道分了多少個(gè)塊組呢?每個(gè)塊組又有多少block多少inode號(hào)等等信息呢?還有,文件系統(tǒng)本身的屬性信息如各種時(shí)間戳、block總數(shù)量和空閑數(shù)量、inode總數(shù)量和空閑數(shù)量、當(dāng)前文件系統(tǒng)是否正常、什么時(shí)候需要自檢等等,它們又存儲(chǔ)在哪里呢?
毫無(wú)疑問(wèn),這些信息必須要存儲(chǔ)在block中。存儲(chǔ)這些信息占用1024字節(jié),所以也要一個(gè)block,這個(gè)block稱(chēng)為超級(jí)塊(superblock),它的block號(hào)可能為0也可能為1。如果block大小為1K,則引導(dǎo)塊正好占用一個(gè)block,這個(gè)block號(hào)為0,所以superblock的號(hào)為1;如果block大小大于1K,則引導(dǎo)塊和超級(jí)塊同置在一個(gè)block中,這個(gè)block號(hào)為0。總之superblock的起止位置是第二個(gè)1024(1024-2047)字節(jié)。
使用df命令讀取的就是每個(gè)文件系統(tǒng)的superblock,所以它的統(tǒng)計(jì)速度非??臁O喾?,用du命令查看一個(gè)較大目錄的已用空間就非常慢,因?yàn)椴豢杀苊獾匾闅v整個(gè)目錄的所有文件。
- [root@xuexi ~]# df -hT
- Filesystem Type Size Used Avail Use% Mounted on
- /dev/sda3 ext4 18G 1.7G 15G 11% /
- tmpfs tmpfs 491M 0 491M 0% /dev/shm
- /dev/sda1 ext4 190M 32M 149M 18% /boot
superblock對(duì)于文件系統(tǒng)而言是至關(guān)重要的,超級(jí)塊丟失或損壞必將導(dǎo)致文件系統(tǒng)的損壞。所以舊式的文件系統(tǒng)將超級(jí)塊備份到每一個(gè)塊組中,但是這又有所空間浪費(fèi),所以ext2文件系統(tǒng)只在塊組0、1和3、5、7冪次方的塊組中保存超級(jí)塊的信息,如Group9、Group25等。盡管保存了這么多的superblock,但是文件系統(tǒng)只使用第一個(gè)塊組即Group0中超級(jí)塊信息來(lái)獲取文件系統(tǒng)屬性,只有當(dāng)Group0上的superblock損壞或丟失才會(huì)找下一個(gè)備份超級(jí)塊復(fù)制到Group0中來(lái)恢復(fù)文件系統(tǒng)。
下圖是一個(gè)ext4文件系統(tǒng)的superblock的信息,ext家族的文件系統(tǒng)都能使用dumpe2fs -h獲取。
2.3 塊組描述符表(GDT)
既然文件系統(tǒng)劃分了塊組,那么每個(gè)塊組的信息和屬性元數(shù)據(jù)又保存在哪里呢?
ext文件系統(tǒng)每一個(gè)塊組信息使用32字節(jié)描述,這32個(gè)字節(jié)稱(chēng)為塊組描述符,所有塊組的塊組描述符組成塊組描述符表GDT(group descriptor table)。
雖然每個(gè)塊組都需要塊組描述符來(lái)記錄塊組的信息和屬性元數(shù)據(jù),但是不是每個(gè)塊組中都存放了塊組描述符。ext文件系統(tǒng)的存儲(chǔ)方式是:將它們組成一個(gè)GDT,并將該GDT存放于某些塊組中,存放GDT的塊組和存放superblock和備份superblock的塊相同,也就是說(shuō)它們是同時(shí)出現(xiàn)在某一個(gè)塊組中的。讀取時(shí)也總是讀取Group0中的塊組描述符表信息。
假如block大小為4KB的文件系統(tǒng)劃分了143個(gè)塊組,每個(gè)塊組描述符32字節(jié),那么GDT就需要143*32=4576字節(jié)即兩個(gè)block來(lái)存放。這兩個(gè)GDT block中記錄了所有塊組的塊組信息,且存放GDT的塊組中的GDT都是完全相同的。
下圖是一個(gè)塊組描述符的信息(通過(guò)dumpe2fs獲取)。
2.4 保留GDT(Reserved GDT)
保留GDT用于以后擴(kuò)容文件系統(tǒng)使用,防止擴(kuò)容后塊組太多,使得塊組描述符超出當(dāng)前存儲(chǔ)GDT的blocks。保留GDT和GDT總是同時(shí)出現(xiàn),當(dāng)然也就和superblock同時(shí)出現(xiàn)了。
例如前面143個(gè)塊組使用了2個(gè)block來(lái)存放GDT,但是此時(shí)第二個(gè)block還空余很多空間,當(dāng)擴(kuò)容到一定程度時(shí)2個(gè)block已經(jīng)無(wú)法再記錄塊組描述符了,這時(shí)就需要分配一個(gè)或多個(gè)Reserved GDT的block來(lái)存放超出的塊組描述符。
由于新增加了GDT block,所以應(yīng)該讓每一個(gè)保存GDT的塊組都同時(shí)增加這一個(gè)GDT block,所以將保留GDT和GDT存放在同一個(gè)塊組中可以直接將保留GDT變換為GDT而無(wú)需使用低效的復(fù)制手段備份到每個(gè)存放GDT的塊組。
同理,新增加了GDT需要修改每個(gè)塊組中superblock中的文件系統(tǒng)屬性,所以將superblock和Reserved GDT/GDT放在一起又能提升效率。
3.Data Block
如上圖,除了Data Blocks其他的部分都解釋過(guò)了。data block是直接存儲(chǔ)數(shù)據(jù)的block,但事實(shí)上并非如此簡(jiǎn)單。
數(shù)據(jù)所占用的block由文件對(duì)應(yīng)inode記錄中的block指針找到,不同的文件類(lèi)型,數(shù)據(jù)block中存儲(chǔ)的內(nèi)容是不一樣的。以下是Linux中不同類(lèi)型文件的存儲(chǔ)方式。
- 對(duì)于常規(guī)文件,文件的數(shù)據(jù)正常存儲(chǔ)在數(shù)據(jù)塊中。
- 對(duì)于目錄,該目錄下的所有文件和一級(jí)子目錄的目錄名存儲(chǔ)在數(shù)據(jù)塊中。
- 文件名不是存儲(chǔ)在其自身的inode中,而是存儲(chǔ)在其所在目錄的data block中。
- 對(duì)于符號(hào)鏈接,如果目標(biāo)路徑名較短則直接保存在inode中以便更快地查找,如果目標(biāo)路徑名較長(zhǎng)則分配一個(gè)數(shù)據(jù)塊來(lái)保存。
- 設(shè)備文件、FIFO和socket等特殊文件沒(méi)有數(shù)據(jù)塊,設(shè)備文件的主設(shè)備號(hào)和次設(shè)備號(hào)保存在inode中。
常規(guī)文件的存儲(chǔ)就不解釋了,下面分別解釋特殊文件的存儲(chǔ)方式。
3.1 目錄文件的data block
對(duì)于目錄文件,其inode記錄中存儲(chǔ)的是目錄的inode號(hào)、目錄的屬性元數(shù)據(jù)和目錄文件的block指針,這里面沒(méi)有存儲(chǔ)目錄自身文件名的信息。
而其data block的存儲(chǔ)方式則如下圖所示。
由圖可知,在目錄文件的數(shù)據(jù)塊中存儲(chǔ)了其下的文件名、目錄名、目錄本身的相對(duì)名稱(chēng)"."和上級(jí)目錄的相對(duì)名稱(chēng)"..",還存儲(chǔ)了指向inode table中這些文件名對(duì)應(yīng)的inode號(hào)的指針(并非直接存儲(chǔ)inode號(hào)碼)、目錄項(xiàng)長(zhǎng)度rec_len、文件名長(zhǎng)度name_len和文件類(lèi)型file_type。注意到除了文件本身的inode記錄了文件類(lèi)型,其所在的目錄的數(shù)據(jù)塊也記錄了文件類(lèi)型。由于rec_len只能是4的倍數(shù),所以需要使用"\0"來(lái)填充name_len不夠湊滿4倍數(shù)的部分。至于rec_len具體是什么,只需知道它是一種偏移即可。
目錄的data block中并沒(méi)有直接存儲(chǔ)目錄中文件的inode號(hào),它存儲(chǔ)的是指向inode table中對(duì)應(yīng)文件inode號(hào)的指針,暫且稱(chēng)之為inode指針(至此,已經(jīng)知道了兩種指針:一種是inode table中每個(gè)inode記錄指向其對(duì)應(yīng)data block的block指針,一個(gè)此處的inode指針。題外話:實(shí)際上inode指針應(yīng)該稱(chēng)之為存儲(chǔ)在目錄data blcok中的鏈接link,這個(gè)link和inode num一一映射,所以刪除文件的函數(shù)稱(chēng)為unlink(),表示在目錄的data block中刪除這個(gè)鏈接)。一個(gè)很有說(shuō)服力的例子,在目錄只有讀而沒(méi)有執(zhí)行權(quán)限的時(shí)候,使用"ls -l"是無(wú)法獲取到其內(nèi)文件inode號(hào)的,這就表明沒(méi)有直接存儲(chǔ)inode號(hào)。實(shí)際上,因?yàn)樵趧?chuàng)建文件系統(tǒng)的時(shí)候,inode號(hào)就已經(jīng)全部劃分好并在每個(gè)塊組的inode table中存放好,inode table在塊組中是有具體位置的,如果使用dumpe2fs查看文件系統(tǒng),會(huì)發(fā)現(xiàn)每個(gè)塊組的inode table占用的block數(shù)量是完全相同的,如下圖是某分區(qū)上其中兩個(gè)塊組的信息,它們都占用249個(gè)block。
除了inode指針,目錄的data block中還使用數(shù)字格式記錄了文件類(lèi)型,數(shù)字格式和文件類(lèi)型的對(duì)應(yīng)關(guān)系如下圖。
注意到目錄的data block中前兩行存儲(chǔ)的是目錄本身的相對(duì)名稱(chēng)"."和上級(jí)目錄的相對(duì)名稱(chēng)"..",它們實(shí)際上是目錄本身的硬鏈接和上級(jí)目錄的硬鏈接。硬鏈接的本質(zhì)后面說(shuō)明。
由此也就容易理解目錄權(quán)限的特殊之處了。目錄文件的讀權(quán)限(r)和寫(xiě)權(quán)限(w),都是針對(duì)目錄文件的數(shù)據(jù)塊本身。由于目錄文件內(nèi)只有文件名、文件類(lèi)型和inode指針,所以如果只有讀權(quán)限,只能獲取文件名和文件類(lèi)型信息,無(wú)法獲取其他信息,盡管目錄的data block中也記錄著文件的inode指針,但定位指針是需要x權(quán)限的,因?yàn)槠渌畔⒍純?chǔ)存在文件自身對(duì)應(yīng)的inode中,而要讀取文件inode信息需要有目錄文件的執(zhí)行權(quán)限通過(guò)inode指針定位到文件對(duì)應(yīng)的inode記錄上。以下是沒(méi)有目錄x權(quán)限時(shí)的查詢(xún)狀態(tài),可以看到除了文件名和文件類(lèi)型,其余的全是"?"。
- [lisi4@xuexi tmp]$ ll -i d
- ls: cannot access d/hehe: Permission denied
- ls: cannot access d/haha: Permission denied
- total 0
- ? d????????? ? ? ? ? ? haha
- ? -????????? ? ? ? ? ? hehe
注意,xfs文件系統(tǒng)和ext文件系統(tǒng)不一樣,它連文件類(lèi)型都無(wú)法獲取。
3.2 符號(hào)鏈接存儲(chǔ)方式
符號(hào)鏈接即為軟鏈接,類(lèi)似于Windows操作系統(tǒng)中的快捷方式,它的作用是指向原文件或目錄。
軟鏈接之所以也被稱(chēng)為特殊文件的原因是:它一般情況下不占用data block,僅僅通過(guò)它對(duì)應(yīng)的inode記錄就能將其信息描述完成;符號(hào)鏈接的大小是其指向目標(biāo)路徑占用的字符個(gè)數(shù),例如某個(gè)符號(hào)鏈接的指向方式為"rmt --> ../sbin/rmt",則其文件大小為11字節(jié);只有當(dāng)符號(hào)鏈接指向的目標(biāo)的路徑名較長(zhǎng)(60個(gè)字節(jié))時(shí)文件系統(tǒng)才會(huì)劃分一個(gè)data block給它;它的權(quán)限如何也不重要,因它只是一個(gè)指向原文件的"工具",最終決定是否能讀寫(xiě)執(zhí)行的權(quán)限由原文件決定,所以很可能ls -l查看到的符號(hào)鏈接權(quán)限為777。
注意,軟鏈接的block指針存儲(chǔ)的是目標(biāo)文件名。也就是說(shuō),鏈接文件的一切都依賴(lài)于其目標(biāo)文件名。這就解釋了為什么/mnt的軟鏈接/tmp/mnt在/mnt掛載文件系統(tǒng)后,通過(guò)軟鏈接就能進(jìn)入/mnt所掛載的文件系統(tǒng)。究其原因,還是因?yàn)槠淠繕?biāo)文件名"/mnt"并沒(méi)有改變。
例如以下篩選出了/etc/下的符號(hào)鏈接,注意觀察它們的權(quán)限和它們占用的空間大小。
- [root@xuexi ~]# ll /etc/ | grep '^l'
- lrwxrwxrwx. 1 root root 56 Feb 18 2016 favicon.png -> /usr/share/icons/hicolor/16x16/apps/system-logo-icon.png
- lrwxrwxrwx. 1 root root 22 Feb 18 2016 grub.conf -> ../boot/grub/grub.conf
- lrwxrwxrwx. 1 root root 11 Feb 18 2016 init.d -> rc.d/init.d
- lrwxrwxrwx. 1 root root 7 Feb 18 2016 rc -> rc.d/rc
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc0.d -> rc.d/rc0.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc1.d -> rc.d/rc1.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc2.d -> rc.d/rc2.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc3.d -> rc.d/rc3.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc4.d -> rc.d/rc4.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc5.d -> rc.d/rc5.d
- lrwxrwxrwx. 1 root root 10 Feb 18 2016 rc6.d -> rc.d/rc6.d
- lrwxrwxrwx. 1 root root 13 Feb 18 2016 rc.local -> rc.d/rc.local
- lrwxrwxrwx. 1 root root 15 Feb 18 2016 rc.sysinit -> rc.d/rc.sysinit
- lrwxrwxrwx. 1 root root 14 Feb 18 2016 redhat-release -> centos-release
- lrwxrwxrwx. 1 root root 11 Apr 10 2016 rmt -> ../sbin/rmt
- lrwxrwxrwx. 1 root root 14 Feb 18 2016 system-release -> centos-release
3.3 設(shè)備文件、FIFO、套接字文件
關(guān)于這3種文件類(lèi)型的文件只需要通過(guò)inode就能完全保存它們的信息,它們不占用任何數(shù)據(jù)塊,所以它們是特殊文件。
設(shè)備文件的主設(shè)備號(hào)和次設(shè)備號(hào)也保存在inode中。以下是/dev/下的部分設(shè)備信息。注意到它們的第5列和第6列信息,它們分別是主設(shè)備號(hào)和次設(shè)備號(hào),主設(shè)備號(hào)標(biāo)識(shí)每一種設(shè)備的類(lèi)型,次設(shè)備號(hào)標(biāo)識(shí)同種設(shè)備類(lèi)型的不同編號(hào);也注意到這些信息中沒(méi)有大小的信息,因?yàn)樵O(shè)備文件不占用數(shù)據(jù)塊所以沒(méi)有大小的概念。
- [root@xuexi ~]# ll /dev | tail
- crw-rw---- 1 vcsa tty 7, 129 Oct 7 21:26 vcsa1
- crw-rw---- 1 vcsa tty 7, 130 Oct 7 21:27 vcsa2
- crw-rw---- 1 vcsa tty 7, 131 Oct 7 21:27 vcsa3
- crw-rw---- 1 vcsa tty 7, 132 Oct 7 21:27 vcsa4
- crw-rw---- 1 vcsa tty 7, 133 Oct 7 21:27 vcsa5
- crw-rw---- 1 vcsa tty 7, 134 Oct 7 21:27 vcsa6
- crw-rw---- 1 root root 10, 63 Oct 7 21:26 vga_arbiter
- crw------- 1 root root 10, 57 Oct 7 21:26 vmci
- crw-rw-rw- 1 root root 10, 56 Oct 7 21:27 vsock
- crw-rw-rw- 1 root root 1, 5 Oct 7 21:26 zero
4.inode基礎(chǔ)知識(shí)
每個(gè)文件都有一個(gè)inode,在將inode關(guān)聯(lián)到文件后系統(tǒng)將通過(guò)inode號(hào)來(lái)識(shí)別文件,而不是文件名。并且訪問(wèn)文件時(shí)將先找到inode,通過(guò)inode中記錄的block位置找到該文件。
4.1 硬鏈接
雖然每個(gè)文件都有一個(gè)inode,但是存在一種可能:多個(gè)文件的inode相同,也就即inode號(hào)、元數(shù)據(jù)、block位置都相同,這是一種什么樣的情況呢?能夠想象這些inode相同的文件使用的都是同一條inode記錄,所以代表的都是同一個(gè)文件,這些文件所在目錄的data block中的inode指針目的地都是一樣的,只不過(guò)各指針對(duì)應(yīng)的文件名互不相同而已。這種inode相同的文件在Linux中被稱(chēng)為"硬鏈接"。
硬鏈接文件的inode都相同,每個(gè)文件都有一個(gè)"硬鏈接數(shù)"的屬性,使用ls -l的第二列就是被硬鏈接數(shù),它表示的就是該文件有幾個(gè)硬鏈接。
- [root@xuexi ~]# ls -l
- total 48
- drwxr-xr-x 5 root root 4096 Oct 15 18:07 700
- -rw-------. 1 root root 1082 Feb 18 2016 anaconda-ks.cfg
- -rw-r--r-- 1 root root 399 Apr 29 2016 Identity.pub
- -rw-r--r--. 1 root root 21783 Feb 18 2016 install.log
- -rw-r--r--. 1 root root 6240 Feb 18 2016 install.log.syslog
例如下圖描述的是dir1目錄中的文件name1及其硬鏈接dir2/name2,右邊分別是它們的inode和datablock。這里也看出了硬鏈接文件之間唯一不同的就是其所在目錄中的記錄不同。注意下圖中有一列Link Count就是標(biāo)記硬鏈接數(shù)的屬性。
每創(chuàng)建一個(gè)文件的硬鏈接,實(shí)質(zhì)上是多一個(gè)指向該inode記錄的inode指針,并且硬鏈接數(shù)加1。
刪除文件的實(shí)質(zhì)是刪除該文件所在目錄data block中的對(duì)應(yīng)的inode指針,所以也是減少硬鏈接次數(shù),由于block指針是存儲(chǔ)在inode中的,所以不是真的刪除數(shù)據(jù),如果仍有其他指針指向該inode,那么該文件的block指針仍然是可用的。當(dāng)硬鏈接次數(shù)為1時(shí)再刪除文件就是真的刪除文件了,此時(shí)inode記錄中block指針也將被刪除。
不能跨分區(qū)創(chuàng)建硬鏈接,因?yàn)椴煌募到y(tǒng)的inode號(hào)可能會(huì)相同,如果允許創(chuàng)建硬鏈接,復(fù)制到另一個(gè)分區(qū)時(shí)inode可能會(huì)和此分區(qū)已使用的inode號(hào)沖突。
硬鏈接只能對(duì)文件創(chuàng)建,無(wú)法對(duì)目錄創(chuàng)建硬鏈接。之所以無(wú)法對(duì)目錄創(chuàng)建硬鏈接,是因?yàn)槲募到y(tǒng)已經(jīng)把每個(gè)目錄的硬鏈接創(chuàng)建好了,它們就是相對(duì)路徑中的"."和"..",分別標(biāo)識(shí)當(dāng)前目錄的硬鏈接和上級(jí)目錄的硬鏈接。每一個(gè)目錄中都會(huì)包含這兩個(gè)硬鏈接,它包含了兩個(gè)信息:(1)一個(gè)沒(méi)有子目錄的目錄文件的硬鏈接數(shù)是2,其一是目錄本身,即該目錄datablock中的".",其二是其父目錄datablock中該目錄的記錄,這兩者都指向同一個(gè)inode號(hào);(2)一個(gè)包含子目錄的目錄文件,其硬鏈接數(shù)是2+子目錄數(shù),因?yàn)槊總€(gè)子目錄都關(guān)聯(lián)一個(gè)父目錄的硬鏈接".."。很多人在計(jì)算目錄的硬鏈接數(shù)時(shí)認(rèn)為由于包含了"."和"..",所以空目錄的硬鏈接數(shù)是2,這是錯(cuò)誤的,因?yàn)?.."不是本目錄的硬鏈接。另外,還有一個(gè)特殊的目錄應(yīng)該納入考慮,即"/"目錄,它自身是一個(gè)文件系統(tǒng)的入口,是自引用(下文中會(huì)解釋自引用)的,所以"/"目錄下的"."和".."的inode號(hào)相同,它自身不占用硬鏈接,因?yàn)槠鋎atablock中只記錄inode號(hào)相同的"."和"..",不再像其他目錄一樣還記錄一個(gè)名為"/"的目錄,所以"/"的硬鏈接數(shù)也是2+子目錄數(shù),但這個(gè)2是"."和".."的結(jié)果。
- [root@xuexi ~]# ln /tmp /mydata
- ln: `/tmp': hard link not allowed for directory
為什么文件系統(tǒng)自己創(chuàng)建好了目錄的硬鏈接就不允許人為創(chuàng)建呢?從"."和".."的用法上考慮,如果當(dāng)前目錄為/usr,我們可以使用"./local"來(lái)表示/usr/local,但是如果我們?nèi)藶閯?chuàng)建了/usr目錄的硬鏈接/tmp/husr,難道我們也要使用"/tmp/husr/local"來(lái)表示/usr/local嗎?這其實(shí)已經(jīng)是軟鏈接的作用了。若要將其認(rèn)為是硬鏈接的功能,這必將導(dǎo)致硬鏈接維護(hù)的混亂。
不過(guò),通過(guò)mount工具的"--bind"選項(xiàng),可以將一個(gè)目錄掛載到另一個(gè)目錄下,實(shí)現(xiàn)偽"硬鏈接",它們的內(nèi)容和inode號(hào)是完全相同的。
硬鏈接的創(chuàng)建方法: ln file_target link_name 。
4.2 軟鏈接
軟鏈接就是字符鏈接,鏈接文件默認(rèn)指的就是字符鏈接文件(注意不是字符設(shè)備),使用"l"表示其類(lèi)型。
硬鏈接不能跨文件系統(tǒng)創(chuàng)建,否則inode號(hào)可能會(huì)沖突。于是實(shí)現(xiàn)了軟鏈接以便跨文件系統(tǒng)建立鏈接。既然是跨文件系統(tǒng),那么軟鏈接必須得有自己的inode號(hào)。
軟鏈接在功能上等價(jià)與Windows系統(tǒng)中的快捷方式,它指向原文件,原文件損壞或消失,軟鏈接文件就損壞。可以認(rèn)為軟鏈接inode記錄中的指針內(nèi)容是目標(biāo)路徑的字符串。
創(chuàng)建方式: ln –s source_file softlink_name ,記住是source_file<--link_name的指向關(guān)系(反箭頭),以前我老搞錯(cuò)位置。
查看軟鏈接的值: readlink softlink_name
在設(shè)置軟鏈接的時(shí)候,source_file雖然不要求是絕對(duì)路徑,但建議給絕對(duì)路徑。是否還記得軟鏈接文件的大小?它是根據(jù)軟鏈接所指向路徑的字符數(shù)計(jì)算的,例如某個(gè)符號(hào)鏈接的指向方式為"rmt --> ../sbin/rmt",它的文件大小為11字節(jié),也就是說(shuō)只要建立了軟鏈接后,軟鏈接的指向路徑是不會(huì)改變的,仍然是"../sbin/rmt"。如果此時(shí)移動(dòng)軟鏈接文件本身,它的指向是不會(huì)改變的,仍然是11個(gè)字符的"../sbin/rmt",但此時(shí)該軟鏈接父目錄下可能根本就不存在/sbin/rmt,也就是說(shuō)此時(shí)該軟鏈接是一個(gè)被破壞的軟鏈接。
5.inode深入
5.1 inode大小和劃分
inode大小為128字節(jié)的倍數(shù),最小為128字節(jié)。它有默認(rèn)值大小,它的默認(rèn)值由/etc/mke2fs.conf文件中指定。不同的文件系統(tǒng)默認(rèn)值可能不同。
- [root@xuexi ~]# cat /etc/mke2fs.conf
- [defaults]
- base_features = sparse_super,filetype,resize_inode,dir_index,ext_attr
- enable_periodic_fsck = 1
- blocksize = 4096
- inode_size = 256
- inode_ratio = 16384
- [fs_types]
- ext3 = {
- features = has_journal
- }
- ext4 = {
- features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize
- inode_size = 256
- }
同樣觀察到這個(gè)文件中還記錄了blocksize的默認(rèn)值和inode分配比率inode_ratio。inode_ratio=16384表示每16384個(gè)字節(jié)即16KB就分配一個(gè)inode號(hào),由于默認(rèn)blocksize=4KB,所以每4個(gè)block就分配一個(gè)inode號(hào)。當(dāng)然分配的這些inode號(hào)只是預(yù)分配,并不真的代表會(huì)全部使用,畢竟每個(gè)文件才會(huì)分配一個(gè)inode號(hào)。但是分配的inode自身會(huì)占用block,而且其自身大小256字節(jié)還不算小,所以inode號(hào)的浪費(fèi)代表著空間的浪費(fèi)。
既然知道了inode分配比率,就能計(jì)算出每個(gè)塊組分配多少個(gè)inode號(hào),也就能計(jì)算出inode table占用多少個(gè)block。
如果文件系統(tǒng)中大量存儲(chǔ)電影等大文件,inode號(hào)就浪費(fèi)很多,inode占用的空間也浪費(fèi)很多。但是沒(méi)辦法,文件系統(tǒng)又不知道你這個(gè)文件系統(tǒng)是用來(lái)存什么樣的數(shù)據(jù),多大的數(shù)據(jù),多少數(shù)據(jù)。
當(dāng)然inodesize、inode分配比例、blocksize都可以在創(chuàng)建文件系統(tǒng)的時(shí)候人為指定。
5.2 ext文件系統(tǒng)預(yù)留的inode號(hào)
Ext預(yù)留了一些inode做特殊特性使用,如下:某些可能并非總是準(zhǔn)確,具體的inode號(hào)對(duì)應(yīng)什么文件可以使用"find / -inum NUM"查看。
- Ext4的特殊inode
- Inode號(hào) 用途
- 0 不存在0號(hào)inode
- 1 虛擬文件系統(tǒng),如/proc和/sys
- 2 根目錄
- 3 ACL索引
- 4 ACL數(shù)據(jù)
- 5 Boot loader
- 6 未刪除的目錄
- 7 預(yù)留的塊組描述符inode
- 8 日志inode
- 11 第一個(gè)非預(yù)留的inode,通常是lost+found目錄
所以在ext4文件系統(tǒng)的dumpe2fs信息中,能觀察到fisrt inode號(hào)可能為11也可能為12。
并且注意到"/"的inode號(hào)為2,這個(gè)特性在文件訪問(wèn)時(shí)會(huì)用上。
需要注意的是,每個(gè)文件系統(tǒng)都會(huì)分配自己的inode號(hào),不同文件系統(tǒng)之間是可能會(huì)出現(xiàn)使用相同inode號(hào)文件的。例如:
- [root@xuexi ~]# find / -ignore_readdir_race -inum 2 -ls
- 2 4 dr-xr-xr-x 22 root root 4096 Jun 9 09:56 /
- 2 2 dr-xr-xr-x 5 root root 1024 Feb 25 11:53 /boot
- 2 0 c--------- 1 root root Jun 7 02:13 /dev/pts/ptmx
- 2 0 -rw-r--r-- 1 root root 0 Jun 6 18:13 /proc/sys/fs/binfmt_misc/status
- 2 0 drwxr-xr-x 3 root root 0 Jun 6 18:13 /sys/fs
從結(jié)果中可見(jiàn),除了根的Inode號(hào)為2,還有幾個(gè)文件的inode號(hào)也是 2,它們都屬于獨(dú)立的文件系統(tǒng),有些是虛擬文件系統(tǒng),如/proc和/sys。
5.3 ext2/3的inode直接、間接尋址
前文說(shuō)過(guò),inode中保存了blocks指針,但是一條inode記錄中能保存的指針數(shù)量是有限的,否則就會(huì)超出inode大小(128字節(jié)或256字節(jié))。
在ext2和ext3文件系統(tǒng)中,一個(gè)inode中最多只能有15個(gè)指針,每個(gè)指針使用i_block[n]表示。
前12個(gè)指針i_block[0]到i_block[11]是直接尋址指針,每個(gè)指針指向一個(gè)數(shù)據(jù)區(qū)的block。如下圖所示。
第13個(gè)指針i_block[12]是一級(jí)間接尋址指針,它指向一個(gè)仍然存儲(chǔ)了指針的block即i_block[12] --> Pointerblock --> datablock。
第14個(gè)指針i_block[13]是二級(jí)間接尋址指針,它指向一個(gè)仍然存儲(chǔ)了指針的block,但是這個(gè)block中的指針還繼續(xù)指向其他存儲(chǔ)指針的block,即i_block[13] --> Pointerblock1 --> PointerBlock2 --> datablock。
第15個(gè)指針i_block[14]是三級(jí)間接尋址指針,它指向一個(gè)任然存儲(chǔ)了指針的block,這個(gè)指針block下還有兩次指針指向。即i_block[13] --> Pointerblock1 --> PointerBlock2 --> PointerBlock3 --> datablock。
其中由于每個(gè)指針大小為4字節(jié),所以每個(gè)指針block能存放的指針數(shù)量為BlockSize/4byte。例如blocksize為4KB,那么一個(gè)Block可以存放4096/4=1024個(gè)指針。
如下圖。
為什么要分間接和直接指針呢?如果一個(gè)inode中15個(gè)指針全是直接指針,假如每個(gè)block的大小為1KB,那么15個(gè)指針只能指向15個(gè)block即15KB的大小,由于每個(gè)文件對(duì)應(yīng)一個(gè)inode號(hào),所以就限制了每個(gè)文件最大為15*1=15KB,這顯然是不合理的。
如果存儲(chǔ)大于15KB的文件而又不太大的時(shí)候,就占用一級(jí)間接指針i_block[12],這時(shí)可以存放指針數(shù)量為1024/4+12=268,所以能存放268KB的文件。
如果存儲(chǔ)大于268K 的文件而又不太大的時(shí)候,就繼續(xù)占用二級(jí)指針i_block[13],這時(shí)可以存放指針數(shù)量為[1024/4]^2+1024/4+12=65804,所以能存放65804KB=64M左右的文件。
如果存放的文件大于64M,那么就繼續(xù)使用三級(jí)間接指針i_block[14],存放的指針數(shù)量為[1024/4]^3+[1024/4]^2+[1024/4]+12=16843020個(gè)指針,所以能存放16843020KB=16GB左右的文件。
如果blocksize=4KB呢?那么最大能存放的文件大小為([4096/4]^3+[4096/4]^2+[4096/4]+12)*4/1024/1024/1024=4T左右。
當(dāng)然這樣計(jì)算出來(lái)的不一定就是最大能存放的文件大小,它還受到另一個(gè)條件的限制。這里的計(jì)算只是表明一個(gè)大文件是如何尋址和分配的。
其實(shí)看到這里的計(jì)算數(shù)值,就知道ext2和ext3對(duì)超大文件的存取效率是低下的,它要核對(duì)太多的指針,特別是4KB大小的blocksize時(shí)。而ext4針對(duì)這一點(diǎn)就進(jìn)行了優(yōu)化,ext4使用extent的管理方式取代ext2和ext3的塊映射,大大提高了效率也降低了碎片。
6 單文件系統(tǒng)中文件操作的原理
在Linux上執(zhí)行刪除、復(fù)制、重命名、移動(dòng)等操作時(shí),它們是怎么進(jìn)行的呢?還有訪問(wèn)文件時(shí)是如何找到它的呢?其實(shí)只要理解了前文中介紹的幾個(gè)術(shù)語(yǔ)以及它們的作用就很容易知道文件操作的原理了。
注:在這一小節(jié)所解釋的都是在單個(gè)文件系統(tǒng)下的行為,在多個(gè)文件系統(tǒng)中如何請(qǐng)看下一個(gè)小節(jié):多文件系統(tǒng)關(guān)聯(lián)。
6.1 讀取文件
當(dāng)執(zhí)行"cat /var/log/messages"命令在系統(tǒng)內(nèi)部進(jìn)行了什么樣的步驟呢?該命令能被成功執(zhí)行涉及了cat命令的尋找、權(quán)限判斷以及messages文件的尋找和權(quán)限判斷等等復(fù)雜的過(guò)程。這里只解釋和本節(jié)內(nèi)容相關(guān)的如何尋找到被cat的/var/log/messages文件。
- 找到根文件系統(tǒng)的塊組描述符表所在的blocks,讀取GDT(已在內(nèi)存中)找到inode table的block號(hào)。
因?yàn)镚DT總是和superblock在同一個(gè)塊組,而superblock總是在分區(qū)的第1024-2047個(gè)字節(jié),所以很容易就知道第一個(gè)GDT所在的塊組以及GDT在這個(gè)塊組中占用了哪些block。
其實(shí)GDT早已經(jīng)在內(nèi)存中了,在系統(tǒng)開(kāi)機(jī)的時(shí)候會(huì)掛載根文件系統(tǒng),掛載的時(shí)候就已經(jīng)將所有的GDT放進(jìn)內(nèi)存中。
- 在inode table的block中定位到根"/"的inode,找出"/"指向的data block。
前文說(shuō)過(guò),ext文件系統(tǒng)預(yù)留了一些inode號(hào),其中"/"的inode號(hào)為2,所以可以根據(jù)inode號(hào)直接定位根目錄文件的data block。
- 在"/"的datablock中記錄了var目錄名和指向var目錄文件inode的指針,并找到該inode記錄,inode記錄中存儲(chǔ)了指向var的block指針,所以也就找到了var目錄文件的data block。
通過(guò)var目錄的inode指針,可以尋找到var目錄的inode記錄,但是指針定位的過(guò)程中,還需要知道該inode記錄所在的塊組以及所在的inode table,所以需要讀取GDT,同樣,GDT已經(jīng)緩存到了內(nèi)存中。
- 在var的data block中記錄了log目錄名和其inode指針,通過(guò)該指針定位到該inode所在的塊組及所在的inode table,并根據(jù)該inode記錄找到log的data block。
- 在log目錄文件的data block中記錄了messages文件名和對(duì)應(yīng)的inode指針,通過(guò)該指針定位到該inode所在的塊組及所在的inode table,并根據(jù)該inode記錄找到messages的data block。
- 最后讀取messages對(duì)應(yīng)的datablock。
將上述步驟中GDT部分的步驟簡(jiǎn)化后比較容易理解。如下:找到GDT-->找到"/"的inode-->找到/的數(shù)據(jù)塊讀取var的inode-->找到var的數(shù)據(jù)塊讀取log的inode-->找到log的數(shù)據(jù)塊讀取messages的inode-->找到messages的數(shù)據(jù)塊并讀取它們。
6.2 刪除、重命名和移動(dòng)文件
注意這里是不跨越文件系統(tǒng)的操作行為。
- 刪除文件分為普通文件和目錄文件,知道了這兩種類(lèi)型的文件的刪除原理,就知道了其他類(lèi)型特殊文件的刪除方法。
對(duì)于刪除普通文件:
(1)找到文件的inode和data block(根據(jù)前一個(gè)小節(jié)中的方法尋找);
(2)將inode table中該inode記錄中的data block指針刪除;
(3)在imap中將該文件的inode號(hào)標(biāo)記為未使用;
(4)在其所在目錄的data block中將該文件名所在的記錄行刪除,刪除了記錄就丟失了指向inode的指針;
(5)將bmap中data block對(duì)應(yīng)的block號(hào)標(biāo)記為未使用。
對(duì)于刪除目錄文件:找到目錄和目錄下所有文件、子目錄、子文件的inode和data block;在imap中將這些inode號(hào)標(biāo)記為未使用;將bmap中將這些文件占用的 block號(hào)標(biāo)記為未使用;在該目錄的父目錄的data block中將該目錄名所在的記錄行刪除。需要注意的是,刪除父目錄data block中的記錄是最后一步,如果該步驟提前,將報(bào)目錄非空的錯(cuò)誤,因?yàn)樵谠撃夸浿羞€有文件占用。
關(guān)于上面的(2)-(5):當(dāng)(2)中刪除data block指針后,將無(wú)法再找到這個(gè)文件的數(shù)據(jù);當(dāng)(3)標(biāo)記inode號(hào)未使用,表示該inode號(hào)可以被后續(xù)的文件重用;當(dāng)(4)刪除目錄data block中關(guān)于該文件的記錄,真正的刪除文件,外界再也定位也無(wú)法看到這個(gè)文件了;當(dāng)(5)標(biāo)記data block為未使用后,表示開(kāi)始釋放空間,這些data block可以被其他文件重用。
注意,在第(5)步之前,由于data block還未被標(biāo)記為未使用,在superblock中仍然認(rèn)為這些data block是正在使用中的。這表示盡管文件已經(jīng)被刪除了,但空間卻還沒(méi)有釋放,df也會(huì)將其統(tǒng)計(jì)到已用空間中(df是讀取superblock中的數(shù)據(jù)塊數(shù)量,并計(jì)算轉(zhuǎn)換為空間大小)。
什么時(shí)候會(huì)發(fā)生這種情況呢?當(dāng)一個(gè)進(jìn)程正在引用文件時(shí)將該文件刪除,就會(huì)出現(xiàn)文件已刪除但空間未釋放的情況。這時(shí)步驟已經(jīng)進(jìn)行到(4),外界無(wú)法再找到該文件,但由于進(jìn)程在加載該文件時(shí)已經(jīng)獲取到了該文件所有的data block指針,該進(jìn)程可以獲取到該文件的所有數(shù)據(jù),但卻暫時(shí)不會(huì)釋放該文件空間。直到該進(jìn)程結(jié)束,文件系統(tǒng)才將未執(zhí)行的步驟(5)繼續(xù)完成。這也是為什么有時(shí)候du的統(tǒng)計(jì)結(jié)果比df小的原因,關(guān)于du和df統(tǒng)計(jì)結(jié)果的差別,詳細(xì)內(nèi)容見(jiàn):詳細(xì)分析du和df的統(tǒng)計(jì)結(jié)果為什么不一樣。
- 重命名文件分為同目錄內(nèi)重命名和非同目錄內(nèi)重命名。非同目錄內(nèi)重命名實(shí)際上是移動(dòng)文件的過(guò)程,見(jiàn)下文。
同目錄內(nèi)重命名文件的動(dòng)作僅僅只是修改所在目錄data block中該文件記錄的文件名部分,不是刪除再重建的過(guò)程。
如果重命名時(shí)有文件名沖突(該目錄內(nèi)已經(jīng)存在該文件名),則提示是否覆蓋。覆蓋的過(guò)程是覆蓋目錄data block中沖突文件的記錄。例如/tmp/下有a.txt和a.log,若將a.txt重命名為a.log,則提示覆蓋,若選擇覆蓋,則/tmp的data block中關(guān)于a.log的記錄被覆蓋,此時(shí)它的指針是指向a.txt的inode。
- 移動(dòng)文件
同文件系統(tǒng)下移動(dòng)文件實(shí)際上是修改目標(biāo)文件所在目錄的data block,向其中添加一行指向inode table中待移動(dòng)文件的inode指針,如果目標(biāo)路徑下有同名文件,則會(huì)提示是否覆蓋,實(shí)際上是覆蓋目錄data block中沖突文件的記錄,由于同名文件的inode記錄指針被覆蓋,所以無(wú)法再找到該文件的data block,也就是說(shuō)該文件被標(biāo)記為刪除(如果多個(gè)硬鏈接數(shù),則另當(dāng)別論)。
所以在同文件系統(tǒng)內(nèi)移動(dòng)文件相當(dāng)快,僅僅在所在目錄data block中添加或覆蓋了一條記錄而已。也因此,移動(dòng)文件時(shí),文件的inode號(hào)是不會(huì)改變的。
對(duì)于不同文件系統(tǒng)內(nèi)的移動(dòng),相當(dāng)于先復(fù)制再刪除的動(dòng)作。見(jiàn)后文。
關(guān)于文件移動(dòng),在Linux環(huán)境下有一個(gè)非常經(jīng)典網(wǎng)上卻又沒(méi)任何解釋的問(wèn)題:/tmp/a/a能覆蓋為/tmp/a嗎?答案是不能,但windows能。為什么不能?見(jiàn)mv的一個(gè)經(jīng)典問(wèn)題(mv的本質(zhì))。
6.3 存儲(chǔ)和復(fù)制文件
- 對(duì)于文件存儲(chǔ)
- (1).讀取GDT,找到各個(gè)(或部分)塊組imap中未使用的inode號(hào),并為待存儲(chǔ)文件分配inode號(hào);
- (2).在inode table中完善該inode號(hào)所在行的記錄;
- (3).在目錄的data block中添加一條該文件的相關(guān)記錄;
- (4).將數(shù)據(jù)填充到data block中。
- 注意,填充到data block中的時(shí)候會(huì)調(diào)用block分配器:一次分配4KB大小的block數(shù)量,當(dāng)填充完4KB的data block后會(huì)繼續(xù)調(diào)用block分配器分配4KB的block,然后循環(huán)直到填充完所有數(shù)據(jù)。也就是說(shuō),如果存儲(chǔ)一個(gè)100M的文件需要調(diào)用block分配器100*1024/4=25600次。
- 另一方面,在block分配器分配block時(shí),block分配器并不知道真正有多少block要分配,只是每次需要分配時(shí)就分配,在每存儲(chǔ)一個(gè)data block前,就去bmap中標(biāo)記一次該block已使用,它無(wú)法實(shí)現(xiàn)一次標(biāo)記多個(gè)bmap位。這一點(diǎn)在ext4中進(jìn)行了優(yōu)化。
- (5)填充完之后,去inode table中更新該文件inode記錄中指向data block的尋址指針。
- 對(duì)于復(fù)制,完全就是另一種方式的存儲(chǔ)文件。步驟和存儲(chǔ)文件的步驟一樣。
7 多文件系統(tǒng)關(guān)聯(lián)
在單個(gè)文件系統(tǒng)中的文件操作和多文件系統(tǒng)中的操作有所不同。本文將對(duì)此做出非常詳細(xì)的說(shuō)明。
7.1 根文件系統(tǒng)的特殊性
這里要明確的是,任何一個(gè)文件系統(tǒng)要在Linux上能正常使用,必須掛載在某個(gè)已經(jīng)掛載好的文件系統(tǒng)中的某個(gè)目錄下,例如/dev/cdrom掛載在/mnt上,/mnt目錄本身是在"/"文件系統(tǒng)下的。而且任意文件系統(tǒng)的一級(jí)掛載點(diǎn)必須是在根文件系統(tǒng)的某個(gè)目錄下,因?yàn)橹挥?/"是自引用的。這里要說(shuō)明掛載點(diǎn)的級(jí)別和自引用的概念。
假如/dev/sdb1掛載在/mydata上,/dev/cdrom掛載在/mydata/cdrom上,那么/mydata就是一級(jí)掛載點(diǎn),此時(shí)/mydata已經(jīng)是文件系統(tǒng)/dev/sdb1的入口了,而/dev/cdrom所掛載的目錄/mydata/cdrom是文件系統(tǒng)/dev/sdb1中的某個(gè)目錄,那么/mydata/cdrom就是二級(jí)掛載點(diǎn)。一級(jí)掛載點(diǎn)必須在根文件系統(tǒng)下,所以可簡(jiǎn)述為:文件系統(tǒng)2掛載在文件系統(tǒng)1中的某個(gè)目錄下,而文件系統(tǒng)1又掛載在根文件系統(tǒng)中的某個(gè)目錄下。
再解釋自引用。首先要說(shuō)的是,自引用的只能是文件系統(tǒng),而文件系統(tǒng)表現(xiàn)形式是一個(gè)目錄,所以自引用是指該目錄的data block中,"."和".."的記錄中的inode指針都指向inode table中同一個(gè)inode記錄,所以它們inode號(hào)是相同的,即互為硬鏈接。而根文件系統(tǒng)是唯一可以自引用的文件系統(tǒng)。
- [root@xuexi /]# ll -ai /
- total 102
- 2 dr-xr-xr-x. 22 root root 4096 Jun 6 18:13 .
- 2 dr-xr-xr-x. 22 root root 4096 Jun 6 18:13 ..
由此也能解釋cd /.和cd /..的結(jié)果都還是在根下,這是自引用最直接的表現(xiàn)形式。
- [root@xuexi tmp]# cd /.
- [root@xuexi /]#
- [root@xuexi tmp]# cd /..
- [root@xuexi /]#
注意,根目錄下的"."和".."都是"/"目錄的硬鏈接,且其datablock中不記錄名為"/"的條目,因此除去根目錄下子目錄數(shù)后的硬鏈接數(shù)為2。
- [root@server2 tmp]# a=$(ls -ld / | awk '{print $2}')
- [root@server2 tmp]# b=$(ls -l / | grep "^d" |wc -l)
- [root@server2 tmp]# echo $((a - b))
- 2
7.2 掛載文件系統(tǒng)的細(xì)節(jié)
掛載文件系統(tǒng)到某個(gè)目錄下,例如"mount /dev/cdrom /mnt",掛載成功后/mnt目錄中的文件全都暫時(shí)不可見(jiàn)了,且掛載后權(quán)限和所有者(如果指定允許普通用戶掛載)等的都改變了,知道為什么嗎?
下面就以通過(guò)"mount /dev/cdrom /mnt"為例,詳細(xì)說(shuō)明掛載過(guò)程中涉及的細(xì)節(jié)。
在將文件系統(tǒng)/dev/cdrom(此處暫且認(rèn)為它是文件系統(tǒng))掛載到掛載點(diǎn)/mnt之前,掛載點(diǎn)/mnt是根文件系統(tǒng)中的一個(gè)目錄,"/"的data block中記錄了/mnt的一些信息,其中包括inode指針inode_n,而在inode table中,/mnt對(duì)應(yīng)的inode記錄中又存儲(chǔ)了block指針block_n,此時(shí)這兩個(gè)指針還是普通的指針。
當(dāng)文件系統(tǒng)/dev/cdrom掛載到/mnt上后,/mnt此時(shí)就已經(jīng)成為另一個(gè)文件系統(tǒng)的入口了,因此它需要連接兩邊文件系統(tǒng)的inode和data block。但是如何連接呢?如下圖。
在根文件系統(tǒng)的inode table中,為/mnt重新分配一個(gè)inode記錄m,該記錄的block指針block_m指向文件系統(tǒng)/dev/cdrom中的data block。既然為/mnt分配了新的inode記錄m,那么在"/"目錄的data block中,也需要修改其inode指針為inode_m以指向m記錄。同時(shí),原來(lái)inode table中的inode記錄n就被標(biāo)記為暫時(shí)不可用。
block_m指向的是文件系統(tǒng)/dev/cdrom的data block,所以嚴(yán)格說(shuō)起來(lái),除了/mnt的元數(shù)據(jù)信息即inode記錄m還在根文件系統(tǒng)上,/mnt的data block已經(jīng)是在/dev/cdrom中的了。這就是掛載新文件系統(tǒng)后實(shí)現(xiàn)的跨文件系統(tǒng),它將掛載點(diǎn)的元數(shù)據(jù)信息和數(shù)據(jù)信息分別存儲(chǔ)在不同的文件系統(tǒng)上。
掛載完成后,將在/proc/self/{mounts,mountstats,mountinfo}這三個(gè)文件中寫(xiě)入掛載記錄和相關(guān)的掛載信息,并會(huì)將/proc/self/mounts中的信息同步到/etc/mtab文件中,當(dāng)然,如果掛載時(shí)加了-n參數(shù),將不會(huì)同步到/etc/mtab。
而卸載文件系統(tǒng),其實(shí)質(zhì)是移除臨時(shí)新建的inode記錄(當(dāng)然,在移除前會(huì)檢查是否正在使用)及其指針,并將指針指回原來(lái)的inode記錄,這樣inode記錄中的block指針也就同時(shí)生效而找回對(duì)應(yīng)的data block了。由于卸載只是移除inode記錄,所以使用掛載點(diǎn)和文件系統(tǒng)都可以實(shí)現(xiàn)卸載,因?yàn)樗鼈兪锹?lián)系在一起的。
下面是分析或結(jié)論。
(1).掛載點(diǎn)掛載時(shí)的inode記錄是新分配的。
# 掛載前掛載點(diǎn)/mnt的inode號(hào)
- [root@server2 tmp]# ll -id /mnt
- 100663447 drwxr-xr-x. 2 root root 6 Aug 12 2015 /mnt
- [root@server2 tmp]# mount /dev/cdrom /mnt
- # 掛載后掛載點(diǎn)的inode號(hào)
- [root@server2 tmp]# ll -id /mnt
- 1856 dr-xr-xr-x 8 root root 2048 Dec 10 2015 mnt
由此可以驗(yàn)證,inode號(hào)確實(shí)是重新分配的。
(2).掛載后,掛載點(diǎn)的內(nèi)容將暫時(shí)不可見(jiàn)、不可用,卸載后文件又再次可見(jiàn)、可用。
- # 在掛載前,向掛載點(diǎn)中創(chuàng)建幾個(gè)文件
- [root@server2 tmp]# touch /mnt/a.txt
- [root@server2 tmp]# mkdir /mnt/abcdir
- # 掛載
- [root@server2 tmp]# mount /dev/cdrom /mnt
- # 掛載后,掛載點(diǎn)中將找不到剛創(chuàng)建的文件
- [root@server2 tmp]# ll /mnt
- total 636
- -r--r--r-- 1 root root 14 Dec 10 2015 CentOS_BuildTag
- dr-xr-xr-x 3 root root 2048 Dec 10 2015 EFI
- -r--r--r-- 1 root root 215 Dec 10 2015
標(biāo)題名稱(chēng):好文分享:EXT文件系統(tǒng)機(jī)制原理詳解
本文路徑:http://www.5511xx.com/article/cooedij.html


咨詢(xún)
建站咨詢(xún)
