ext2文件系統(tǒng)詳解,一文解決!
第一部分磁盤的物理組成
磁盤的基本概念: 扇區(qū)為最小的物理存儲(chǔ)單位,每個(gè)扇區(qū)為512字節(jié)。 將扇區(qū)組成一個(gè)圓,那就是柱面,柱面是分區(qū)的最小單位。 第一個(gè)扇區(qū)很重要,里面有硬盤主引導(dǎo)記錄(Masterbootrecord,MBR)及分區(qū)表,其中MBR占有446字節(jié),分區(qū)表占有64字節(jié)。 各種接口的磁盤在Linux中的文件名 ①/dev/sd[a-p][1-15]:為SCSI,SATA,USB,F(xiàn)lash等接口的磁盤文件名; ②/dev/hd[a-d][1-63]:為IDE接口的磁盤文件名。
磁盤分區(qū) 是告訴操作系統(tǒng)“我這塊磁盤在此分區(qū)可以訪問的區(qū)域是A柱面到B柱面之間的塊”,這樣操作系統(tǒng)就知道它可以在所指定的塊內(nèi)進(jìn)行文件數(shù)據(jù)的讀、寫、查找等操作。磁盤分區(qū)即指定分區(qū)的起始與結(jié)束柱面。 而指定分區(qū)的柱面范圍記錄在第一個(gè)扇區(qū)的分區(qū)表中。因?yàn)榉謪^(qū)表只有64字節(jié)(每個(gè)分區(qū)項(xiàng)占用16個(gè)字節(jié),這16個(gè)字節(jié)中存有活動(dòng)狀態(tài)標(biāo)志、文件系統(tǒng)標(biāo)識(shí)、起止柱面號、磁頭號、扇區(qū)號、隱含扇區(qū)數(shù)目(4個(gè)字節(jié))、分區(qū)總扇區(qū)數(shù)目(4個(gè)字節(jié))等內(nèi)容。),所以最多只能記錄4條分區(qū)的記錄,這四條記錄稱為主分區(qū) 或擴(kuò)展分區(qū) 。擴(kuò)展分區(qū)還可以再分出邏輯分區(qū) 。擴(kuò)展分區(qū)最多只能有一個(gè)(操作系統(tǒng)限制),主分區(qū)和邏輯分區(qū)的內(nèi)容可以被格式化,而擴(kuò)展分區(qū)不能格式化。 注:MBR分區(qū)方案無法支持超過2TB容量的磁盤。因?yàn)檫@一方案用4個(gè)字節(jié)存儲(chǔ)分區(qū)的總扇區(qū)數(shù),最大能表示2的32次方的扇區(qū)個(gè)數(shù),按每扇區(qū)512字節(jié)計(jì)算,每個(gè)分區(qū)最大不能超過2TB。磁盤容量超過2TB以后,分區(qū)的起始位置也就無法表示了。 一個(gè)磁盤可以劃分成多個(gè)分區(qū),每個(gè)分區(qū)必須先用格式化工具(如mkfs命令)格式化成某種格式的文件系統(tǒng) ,然后才能存儲(chǔ)文件,格式化過程中會(huì)在磁盤上寫一些管理存儲(chǔ)布局的信息。一個(gè)分區(qū)只能格式化成一個(gè)文件系統(tǒng)
文件系統(tǒng)特性我們都知道磁盤分區(qū)完畢后還需要進(jìn)行格式化(format),之后操作系統(tǒng)才能夠使用這個(gè)分區(qū)。 為什么需要進(jìn)行『格式化』呢?這是因?yàn)槊糠N操作系統(tǒng)所配置的文件屬性/權(quán)限并不相同, 為了存放這些文件所需的數(shù)據(jù),因此就需要將分區(qū)進(jìn)行格式化,以成為操作系統(tǒng)能夠利用的『文件系統(tǒng)格式(filesystem)』。 傳統(tǒng)的磁盤與文件系統(tǒng)之應(yīng)用中,一個(gè)分區(qū)就是只能夠被格式化成為一個(gè)文件系統(tǒng),所以我們可以說一個(gè) filesystem 就是一個(gè) partition。但是由于新技術(shù)的利用,例如我們常聽到的LVM與軟件磁盤陣列(software raid), 這些技術(shù)可以將一個(gè)分區(qū)格式化為多個(gè)文件系統(tǒng)(例如LVM),也能夠?qū)⒍鄠€(gè)分區(qū)合成一個(gè)文件系統(tǒng)(LVM, RAID)! 所以說,目前我們在格式化時(shí)已經(jīng)不再說成針對 partition 來格式化了, 通常我們可以稱呼一個(gè)可被掛載的數(shù)據(jù)為一個(gè)文件系統(tǒng)而不是一個(gè)分區(qū)。 那么文件系統(tǒng)是如何運(yùn)行的呢?這與操作系統(tǒng)的文件數(shù)據(jù)有關(guān)。較新的操作系統(tǒng)的文件數(shù)據(jù)除了文件實(shí)際內(nèi)容外, 通常含有非常多的屬性,例如 Linux 操作系統(tǒng)的文件權(quán)限(rwx)與文件屬性(擁有者、群組、時(shí)間參數(shù)等)。 文件系統(tǒng)通常會(huì)將這兩部份的數(shù)據(jù)分別存放在不同的區(qū)塊,權(quán)限與屬性放置到 inode 中,至于實(shí)際數(shù)據(jù)則放置到 data block 區(qū)塊中。 另外,還有一個(gè)超級區(qū)塊 (superblock) 會(huì)記錄整個(gè)文件系統(tǒng) 的整體信息,包括 inode 與 block 的總量、使用量、剩余量等。
每個(gè) inode 與 block 都有編號,至于這三個(gè)數(shù)據(jù)的意義可以簡略說明如下:
superblock :記錄此 filesystem 的整體信息,包括inode/block的總量、使用量、剩余量, 以及文件系統(tǒng)的格式與相關(guān)信息等;inode :記錄文件的屬性,一個(gè)文件占用一個(gè)inode,同時(shí)記錄此文件的數(shù)據(jù)所在的 block 號碼;block :實(shí)際記錄文件的內(nèi)容,若文件太大時(shí),會(huì)占用多個(gè) block 。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ?


ext2文件系統(tǒng)


文件系統(tǒng)中存儲(chǔ)的最小單元是塊(block),一個(gè)塊的大小是在格式化時(shí)確定的。啟動(dòng)塊(Boot Block)的大小為1KB,由PC標(biāo)準(zhǔn)規(guī)定,用來存儲(chǔ)磁盤分區(qū)信息和啟動(dòng)信息,任何文件系統(tǒng)都不能修改啟動(dòng)塊。 啟動(dòng)塊之后才是ext2文件系統(tǒng)的開始,ext2文件系統(tǒng)將整個(gè)分區(qū)劃分成若干個(gè)同樣大小的塊組 (Block Group)。 在整體的規(guī)劃當(dāng)中,文件系統(tǒng)最前面有一個(gè)啟動(dòng)扇區(qū) (boot sector),這個(gè)啟動(dòng)扇區(qū)可以安裝啟動(dòng)管理程序, 這是個(gè)非常重要的設(shè)計(jì),因?yàn)槿绱艘粊砦覀兙湍軌驅(qū)⒉煌膯?dòng)管理程序安裝到個(gè)別的文件系統(tǒng)最前端,而不用覆蓋整顆硬盤唯一的 MBR, 這樣也才能夠制作出多重引導(dǎo)的環(huán)境啊!至于每一個(gè)區(qū)塊群組(block group)的六個(gè)主要內(nèi)容說明如后:
每個(gè)塊組的組成 : 1)超級塊 (Super Block)描述整個(gè)分區(qū) 的文件系統(tǒng)信息,如inode/block的大小、總量、使用量、剩余量,以及文件系統(tǒng)的格式與相關(guān)信息。超級塊在每個(gè)塊組的開頭都有一份拷貝(第一個(gè)塊組必須有,后面的塊組可以沒有)。 為了保證文件系統(tǒng)在磁盤部分扇區(qū)出現(xiàn)物理問題的情況下還能正常工作,就必須保證文件系統(tǒng)的super block信息在這種情況下也能正常訪問。所以一個(gè)文件系統(tǒng)的super block會(huì)在多個(gè)block group中進(jìn)行備份,這些super block區(qū)域的數(shù)據(jù)保持一致。 超級塊記錄的信息有:
1、block 與 inode 的總量(分區(qū)內(nèi)所有Block Group的block和inode總量); 2、未使用與已使用的 inode / block 數(shù)量; 3、block 與 inode 的大小 (block 為 1, 2, 4K,inode 為 128 bytes); 4、filesystem 的掛載時(shí)間、最近一次寫入數(shù)據(jù)的時(shí)間、最近一次檢驗(yàn)磁盤 (fsck) 的時(shí)間等文件系統(tǒng)的相關(guān)信息; 5、一個(gè) valid bit 數(shù)值,若此文件系統(tǒng)已被掛載,則 valid bit 為 0 ,若未被掛載,則 valid bit 為 1 。
每個(gè)區(qū)段與 superblock 的信息都可以使用 dumpe2fs 這個(gè)命令查詢 2)塊組描述符表 (GDT,Group Descriptor Table)由很多塊組描述符組成,整個(gè)分區(qū)分成多個(gè)塊組就對應(yīng)有多少個(gè)塊組描述符。 每個(gè)塊組描述符存儲(chǔ)一個(gè)塊組 的描述信息,如在這個(gè)塊組中從哪里開始是inode Table,從哪里開始是Data Blocks,空閑的inode和數(shù)據(jù)塊還有多少個(gè)等等。塊組描述符在每個(gè)塊組的開頭都有一份拷貝。 3)塊位圖 (Block Bitmap)用來描述整個(gè)塊組中哪些塊已用哪些塊空閑。塊位圖本身占一個(gè)塊,其中的每個(gè)bit代表本塊組的一個(gè)block,這個(gè)bit為1代表該塊已用,為0表示空閑可用。假設(shè)格式化時(shí)block大小為1KB,這樣大小的一個(gè)塊位圖就可以表示1024*8個(gè)塊的占用情況,因此一個(gè)塊組最多可以有10248個(gè)塊。 4)inode位圖 (inode Bitmap)和塊位圖類似,本身占一個(gè)塊,其中每個(gè)bit表示一個(gè)inode是否空閑可用。 Inode bitmap的作用是記錄block group中Inode區(qū)域的使用情況,Ext文件系統(tǒng)中一個(gè)block group中可以有16384個(gè)Inode,代表著這個(gè)Ext文件系統(tǒng)中一個(gè)block group最多可以描述16384個(gè)文件。 5)inode表 (inode Table)由一個(gè)塊組中的所有inode組成。一個(gè)文件除了數(shù)據(jù)需要存儲(chǔ)之外,一些描述信息也需要存儲(chǔ),如文件類型,權(quán)限,文件大小,創(chuàng)建、修改、訪問時(shí)間等,這些信息存在inode中而不是數(shù)據(jù)塊中。inode表占多少個(gè)塊在格式化時(shí)就要寫入塊組描述符中。 在Ext2/Ext3文件系統(tǒng)中,每個(gè)文件在磁盤上的位置都由文件系統(tǒng)block group中的一個(gè)Inode指針進(jìn)行索引,Inode將會(huì)把具體的位置指向一些真正記錄文件數(shù)據(jù)的block塊,需要注意的是這些block可能和Inode同屬于一個(gè)block group也可能分屬于不同的block group。我們把文件系統(tǒng)上這些真實(shí)記錄文件數(shù)據(jù)的block稱為Data blocks。 Inode Table和單個(gè)Inode 結(jié)構(gòu)

inode記錄的文件數(shù)據(jù)至少有:(都是文件屬性與權(quán)限描述信息)
該文件的訪問模式(rwx) 該文件的所有者與組(owner/group) 該文件的大小 該文件創(chuàng)建或狀態(tài)改變的時(shí)間(ctime) 最近一次的讀取時(shí)間(atime) 最近修改內(nèi)容的時(shí)間(mtime) 定義文件特性的標(biāo)志(flag),如SetUID等 該文件真正內(nèi)容的指向(Pointer)
Ext2/Ext3文件系統(tǒng)中,采用Inode指針和Data block地址進(jìn)行直接/間接關(guān)聯(lián)的方式記錄文件數(shù)據(jù)。一個(gè)Inode指針要么不對應(yīng)任何文件的Data block,要么對應(yīng)一個(gè)文件的一個(gè)或者多個(gè)Data block。在Ext3文件系統(tǒng)中一個(gè)Inode指針的長度為4字節(jié),按照一個(gè)字節(jié)8個(gè)bit計(jì)算Ext3文件系統(tǒng)中的Inode指針支持32位Data block尋址(2 ^ 32個(gè)地址);到了Ext4文件系統(tǒng),雖然它不再使用Inode指針,但同樣有地址索引的概念,并且長度擴(kuò)展到了6字節(jié),那么按照一個(gè)字節(jié)8個(gè)bit計(jì)算,Ext4文件系統(tǒng)中的索引支持48位Data block尋址(2 ^ 48個(gè)地址)。所以如果按照單個(gè)Data block記錄4KB數(shù)據(jù)大小來計(jì)算,Ext3文件系統(tǒng)支持的最大理論總?cè)萘烤褪牵? ^ 32 *4KB / 1024 / 1024 / 1024 = 16TB,而Ext4文件系統(tǒng)支持的最大理論總?cè)萘烤褪?2 ^ 48 *4KB / 1024 / 1024 / 1024 = 1,048,576TB = 1024 *1024TB。
Ext2/Ext3文件系統(tǒng)的Inode信息存放在block group的Inode Table區(qū)域,這個(gè)區(qū)域的默認(rèn)大小為512個(gè)block,那么再根據(jù)文件系統(tǒng)中單個(gè)Inode的大小就可以得到每個(gè)block group所管理的Inode總數(shù)。例如當(dāng)單位Inode的大小為256字節(jié),得出每個(gè)block group所管理的Inode總數(shù)為 512 **4096字節(jié) / 256字節(jié) = 8192(Ext4文件系統(tǒng));當(dāng)Inode的大小為128字節(jié),得出每個(gè)block group所管理的Inode總數(shù)為 512 * 4096字節(jié) / 128字節(jié) = 16384 (Ext3文件系統(tǒng))
inode 的數(shù)量與大小也是在格式化時(shí)就已經(jīng)固定了,除此之外 inode 還有些什么特色呢?
每個(gè) inode 大小均固定為 128 bytes; 每個(gè)文件都僅會(huì)占用一個(gè) inode 而已; 承上,因此文件系統(tǒng)能夠創(chuàng)建的文件數(shù)量與 inode 的數(shù)量有關(guān); 系統(tǒng)讀取文件時(shí)需要先找到 inode,并分析 inode 所記錄的權(quán)限與用戶是否符合,若符合才能夠開始實(shí)際讀取 block 的內(nèi)容。
我們約略來分析一下 inode / block 與文件大小的關(guān)系好了。inode 要記錄的數(shù)據(jù)非常多,但偏偏又只有 128bytes 而已, 而 inode 記錄一個(gè) block 號碼要花掉 4byte ,假設(shè)我一個(gè)文件有 400MB 且每個(gè) block 為 4K 時(shí), 那么至少也要十萬筆 block 號碼的記錄呢!inode 哪有這么多可記錄的信息?為此我們的系統(tǒng)很聰明的將 inode 記錄 block 號碼的區(qū)域定義為12個(gè)直接,一個(gè)間接, 一個(gè)雙間接與一個(gè)三間接記錄區(qū)。這是啥?我們將 inode 的結(jié)構(gòu)畫一下好了。
數(shù)據(jù)塊尋址 :(ext2是索引式文件系統(tǒng)(indexed allocation))

一個(gè)inode占128字節(jié),其中60個(gè)字節(jié)用于指向存放文件內(nèi)容的數(shù)據(jù)塊指針。每個(gè)指針4字節(jié),那么有15個(gè)指針。最后3個(gè)指針用分級間接尋址。 假設(shè)block為1KB。

12個(gè)直接指向,可以有12條記錄。 一級間接尋址:1024/4=256,可以有256條記錄。 二級間接尋址,可以有256* 256條記錄。 三級間接尋址,可以有256 * 256 *256條記錄。 所以對于1KB的塊大小最大可以表示(256^3 +256^2+256+12)*1KB≈16GB的文件。
6)數(shù)據(jù)塊 (Data Block)是用來放置文件內(nèi)容數(shù)據(jù)的地方。根據(jù)不同的文件類型有以下幾種情況: 對于普通文件,文件的數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)塊中。 對于目錄,該目錄下的所有文件名和目錄名存儲(chǔ)在所在目錄的數(shù)據(jù)塊中,除了文件名外,ls -l命令看到的其它信息保存在該文件的inode中。 對于符合鏈接,如果目標(biāo)路徑名較短則直接保存在inode中,如果較長則分配一個(gè)數(shù)據(jù)塊來保存。 設(shè)備文件、FIFO和socket等特殊文件沒有數(shù)據(jù)塊。
data block 是用來放置文件內(nèi)容數(shù)據(jù)地方,在 Ext2 文件系統(tǒng)中所支持的 block 大小有 1K, 2K 及 4K 三種而已。在格式化時(shí) block 的大小就固定了,且每個(gè) block 都有編號,以方便 inode 的記錄啦。 不過要注意的是,由于 block 大小的差異,會(huì)導(dǎo)致該文件系統(tǒng)能夠支持的最大磁盤容量與最大單一文件容量并不相同。 因?yàn)?block 大小而產(chǎn)生的 Ext2 文件系統(tǒng)限制如下: Block 大小 1KB 2KB 4KB 最大單一文件限制 16GB 256GB 2TB 最大文件系統(tǒng)總?cè)萘?2TB 8TB 16TB
你需要注意的是,雖然 Ext2 已經(jīng)能夠支持大于 2GB 以上的單一文件容量,不過某些應(yīng)用程序依然使用舊的限制, 也就是說,某些程序只能夠捉到小于 2GB 以下的文件而已,這就跟文件系統(tǒng)無關(guān)了!
除此之外 Ext2 文件系統(tǒng)的 block 還有什么限制呢?有的!基本限制如下:
原則上,block 的大小與數(shù)量在格式化完就不能夠再改變了(除非重新格式化); 每個(gè) block 內(nèi)最多只能夠放置一個(gè)文件的數(shù)據(jù); 承上,如果文件大于 block 的大小,則一個(gè)文件會(huì)占用多個(gè) block 數(shù)量; 承上,若文件小于 block ,則該 block 的剩余容量就不能夠再被使用了(磁盤空間會(huì)浪費(fèi))。 如上第四點(diǎn)所說,由于每個(gè) block 僅能容納一個(gè)文件的數(shù)據(jù)而已,因此如果你的文件都非常小,但是你的 block 在格式化時(shí)卻選用最大的 4K 時(shí),可能會(huì)產(chǎn)生一些容量的浪費(fèi)喔!我們以底下的一個(gè)簡單例題來算一下空間的浪費(fèi)吧!
例題: 假設(shè)你的Ext2文件系統(tǒng)使用 4K block ,而該文件系統(tǒng)中有 10000 個(gè)小文件,每個(gè)文件大小均為 50bytes, 請問此時(shí)你的磁盤浪費(fèi)多少容量? 答: 由于 Ext2 文件系統(tǒng)中一個(gè) block 僅能容納一個(gè)文件,因此每個(gè) block 會(huì)浪費(fèi)『 4096 - 50 = 4046 (byte)』, 系統(tǒng)中總共有一萬個(gè)小文件,所有文件容量為:50 (bytes) x 10000 = 488.3Kbytes,但此時(shí)浪費(fèi)的容量為:『 4046 (bytes) x 10000 = 38.6MBytes 』。想一想,不到 1MB 的總文件容量卻浪費(fèi)將近 40MB 的容量,且文件越多將造成越多的磁盤容量浪費(fèi)。
什么情況會(huì)產(chǎn)生上述的狀況呢?例如 BBS 網(wǎng)站的數(shù)據(jù)啦!如果 BBS 上面的數(shù)據(jù)使用的是純文本文件來記載每篇留言, 而留言內(nèi)容如果都寫上『如題』時(shí),想一想,是否就會(huì)產(chǎn)生很多小文件了呢?
好,既然大的 block 可能會(huì)產(chǎn)生較嚴(yán)重的磁盤容量浪費(fèi),那么我們是否就將 block 大小訂為 1K 即可? 這也不妥,因?yàn)槿绻?block 較小的話,那么大型文件將會(huì)占用數(shù)量更多的 block ,而 inode 也要記錄更多的 block 號碼,此時(shí)將可能導(dǎo)致文件系統(tǒng)不良的讀寫效能。
所以我們可以說,在您進(jìn)行文件系統(tǒng)的格式化之前,請先想好該文件系統(tǒng)預(yù)計(jì)使用的情況。 以鳥哥來說,我的數(shù)值模式仿真平臺(tái)隨便一個(gè)文件都好幾百 MB,那么 block 容量當(dāng)然選擇較大的!至少文件系統(tǒng)就不必記錄太多的 block 號碼,讀寫起來也比較方便??!
ext2寫入過程Linux操作系統(tǒng)為了加快I/O操作過程,當(dāng)有文件需要寫入文件系統(tǒng)時(shí)Linux操作系統(tǒng)并不會(huì)立刻將文件數(shù)據(jù)實(shí)際寫入data block,而是存儲(chǔ)到一個(gè)內(nèi)存區(qū)塊中。如果您通過top命令或者Free命令,就可以看到這個(gè)名叫cache memory的內(nèi)存區(qū)塊。
[root@lab-backup ~]# free
? ? ? ? total ? ? ? used ? ? ? free ? ? shared ? ?buffers ? ? cached
Mem: ? ? ? 3805272 ? ?3662628 ? ? 142644 ? ? ? ?508 ? ?1758376 ? ?1491128
-/+ buffers/cache: ? ? 413124 ? ?3392148
Swap: ? ? ?3948540 ? ? ? ? ?0 ? ?3948540
無論是Ext2文件系統(tǒng)還是Ext3文件系統(tǒng)又或者是Ext4文件系統(tǒng),寫入cache memory區(qū)塊的這個(gè)過程是不會(huì)改變的。以上示例效果中還有一個(gè)叫做buffers memory的內(nèi)存區(qū)塊,這個(gè)區(qū)塊緩存了文件系統(tǒng)的部分Inode信息,這樣保證了操作系統(tǒng)不會(huì)隨時(shí)到文件系統(tǒng)上尋找Inode——優(yōu)化文件系統(tǒng)的讀性能。cache memory區(qū)塊和buffers memory區(qū)塊由操作系統(tǒng)自行管理,它們只會(huì)使用當(dāng)前沒有被應(yīng)用程序占用的空閑內(nèi)存。當(dāng)應(yīng)用程序請求新的內(nèi)存區(qū)塊且空閑內(nèi)存不夠時(shí),操作系統(tǒng)會(huì)釋放部分cache memory區(qū)塊或者buffers memory區(qū)塊。后文我們講解Linux下的Page Cache技術(shù)時(shí),還會(huì)對這部分知識(shí)進(jìn)行詳細(xì)講解。當(dāng)cache memory區(qū)塊寫滿或者到達(dá)一個(gè)等待時(shí)間后,操作系統(tǒng)就會(huì)正式開始向文件系統(tǒng)寫數(shù)據(jù)了。
在Ext2文件系統(tǒng)中,完成文件寫入的過程可以簡要的進(jìn)行如下描述:首先文件系統(tǒng)會(huì)在收到文件寫入請求后根據(jù)算法尋找一個(gè)還沒有使用的Inode,這個(gè)算法過程根據(jù)不同文件系統(tǒng)小版本和Linux內(nèi)核版本的不同而有所變化,但尋找原則都是一樣的,即盡可能為文件尋找連續(xù)的inode和data block。上文已經(jīng)提到Ext文件系統(tǒng)中,每一個(gè)block group都有Block bitmap區(qū)域和Inode bitmap區(qū)域分別用于記錄block group中的block和Inode的使用情況。在尋找Inode的這個(gè)步驟中,block group的Block bitmap、Inode bitmap區(qū)域還不會(huì)被寫入任何變化,block group的Group description table區(qū)域也不會(huì)被寫入任何變化。
接下來Ext2文件系統(tǒng)就要向硬件層正式寫入數(shù)據(jù)了,這個(gè)步驟還包括建立Inode和data block的關(guān)聯(lián)信息。最后當(dāng)文件系統(tǒng)相對空閑的情況下,文件系統(tǒng)才會(huì)更新block group中的Block bitmap、Inode bitmap和Group description table區(qū)域。正常情況下這種操作過程并沒有太大的問題,因?yàn)槲募到y(tǒng)隨時(shí)都清楚哪些Block bitmap、Inode bitmap被真正使用了,哪些Block bitmap、Inode bitmap是被使用但還沒有來得及更改狀態(tài)。當(dāng)文件系統(tǒng)正常關(guān)閉時(shí)Ext2文件系統(tǒng)會(huì)設(shè)置一個(gè)校驗(yàn)標(biāo)記Valid bit=1,表示本次文件系統(tǒng)的操作正常結(jié)束。
但是如果當(dāng)文件系統(tǒng)因?yàn)楦鞣N原因異常關(guān)閉時(shí)(例如斷電)這個(gè)標(biāo)記的值就為0,那么問題就來了。因?yàn)槟男┮呀?jīng)被使用但還沒有來得及被標(biāo)示的Block bitmap、Inode bitmap區(qū)域,和真實(shí)的使用情況就存在誤差了。雖然操作系統(tǒng)下次啟動(dòng)時(shí)會(huì)對整個(gè)文件系統(tǒng)進(jìn)行掃描試圖恢復(fù)操作(主要目的是恢復(fù)Block bitmap、Inode bitmap和真實(shí)事情情況的一致性),但是操作系統(tǒng)并不保證一致性被全部恢復(fù)。這樣看來Ext2文件系統(tǒng)的寫入過程至少存在一下幾個(gè)問題:
由于data block塊的寫入操作和Block bitmap、Inode bitmap區(qū)域的更新過程是分開進(jìn)行的,所以當(dāng)系統(tǒng)異常關(guān)閉時(shí)Ext2文件系統(tǒng)并不能保證Block bitmap、Inode bitmap的狀態(tài)和真實(shí)的block使用情況完全一致。所以才會(huì)有系統(tǒng)重啟時(shí)試圖恢復(fù)磁盤一致性的修復(fù)操作。
Ext2文件系統(tǒng)對于大文件的讀寫性能并不好,這是因?yàn)楫?dāng)文件特別大時(shí),Ext2文件系統(tǒng)會(huì)啟用三級間接指針和四級間接指針建立Inode和data block的聯(lián)系。雖然當(dāng)data block size為4KB時(shí)單個(gè)文件的大小可達(dá)4TB,但是因?yàn)榇鎯?chǔ)大文件時(shí)會(huì)啟用二級、三級甚至四級間接指針,這大大增加了文件系統(tǒng)上的索引查找時(shí)間。所以這種多級索引的思路除了可以增加單個(gè)文件容量外,對提升大文件的讀寫性能實(shí)際上并沒有太多幫助。
另外Ext2文件系統(tǒng)在向data block寫入文件數(shù)據(jù)時(shí),將以data block size(默認(rèn)為4KB)為單位依次向硬件層提交數(shù)據(jù),這就是為什么在其它設(shè)置不變的情況下,如果將Ext2文件系統(tǒng)的data block size格式化為8KB,會(huì)增加一定的磁盤讀寫性能的原因。
Ext3日志模式 以上小節(jié)中提到的Ext2文件系統(tǒng)的明顯問題中,最嚴(yán)重的應(yīng)該還是文件系統(tǒng)異常情況下Block bitmap、Inode bitmap可能出現(xiàn)的一致性問題。所以Ext3文件系統(tǒng)在基本保持Ext2文件系統(tǒng)組織結(jié)構(gòu)的前提下,使用索引日志的思路來解決Ext2文件系統(tǒng)上的數(shù)據(jù)一致性問題。
Ext3文件系統(tǒng)又被稱為日志文件系統(tǒng),它在Ext2文件系統(tǒng)的基礎(chǔ)上做的主要改動(dòng)就是,在正式寫入data block數(shù)據(jù)并建立Inode索引前,通過在磁盤上的某塊固定位置寫入一段日志數(shù)據(jù)的方式建立這兩個(gè)操作過程的關(guān)系,并根據(jù)后續(xù)操作進(jìn)行日志數(shù)據(jù)的保留/刪除,以達(dá)到保持操作一致性的目的。這樣一來,即使文件系統(tǒng)上一次異常關(guān)閉,當(dāng)文件系統(tǒng)再次啟動(dòng)時(shí)也不需要再進(jìn)行整個(gè)文件系統(tǒng)Inode和data block掃描了,只需要重新加載日志數(shù)據(jù)文件系統(tǒng)就可以知道上一次異常關(guān)閉時(shí)還有哪些Block bitmap、Inode bitmap沒有處理完。
Ext3文件系統(tǒng)支持三種日志模式,他們在數(shù)據(jù)一致性和I/O性能上有所區(qū)別:
journal日志模式
在這種模式下,當(dāng)文件系統(tǒng)正式開始進(jìn)行磁盤操作前會(huì)在磁盤的上專門的日志區(qū)域創(chuàng)建這個(gè)文件的副本,包括這個(gè)文件的Inode和data block完整信息,副本創(chuàng)建完成后才會(huì)按照正常的寫入過程進(jìn)行文件寫入。當(dāng)寫入操作正常完成后,文件系統(tǒng)會(huì)刪除日志區(qū)域的文件副本。這樣一來當(dāng)文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序會(huì)掃描日志區(qū)域中的副本:如果發(fā)現(xiàn)文件副本本身就不完整,則會(huì)丟棄這部分副本。如果發(fā)現(xiàn)文件副本是完整的,則會(huì)繼續(xù)完成正式文件的寫入過程,最后刪除文件副本。很顯然journal日志模式會(huì)增加單個(gè)文件的磁盤操作次數(shù),所以journal日志模式是三種日志模式中速度最慢的一種。但是journal日志模式卻可以做到最完整的數(shù)據(jù)一致性要求。
ordered日志模式
ordered日志模式是Ext3/Ext4文件系統(tǒng)默認(rèn)的日志模式。這種模式比 journal日志模式快了許多,因?yàn)閛rdered日志模式下Ext文件系統(tǒng)的日志區(qū)域并沒有真正記錄文件的真實(shí)數(shù)據(jù),不會(huì)發(fā)生一個(gè)文件的多次讀寫過程。當(dāng)文件系統(tǒng)為新文件確定了Inode和block區(qū)域后,這些Inode、Block bitmap、Inode bitmap等索引信息將會(huì)首先保存到文件系統(tǒng)的日志區(qū)域,并形成一個(gè)事務(wù)單位。當(dāng)文件數(shù)據(jù)被完整寫入磁盤對應(yīng)的block后,文件系統(tǒng)才會(huì)將日志區(qū)域的Inode信息和block信息提交到對應(yīng)的block group中,完成整個(gè)寫入過程。當(dāng)文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序會(huì)掃描日志區(qū)域中的副本:如果發(fā)現(xiàn)還有事務(wù)單位沒有被提交,那么磁盤上對應(yīng)的block位置上的信息將被清除,以保持文件信息一致性。
writeback日志模式
這是一種異步日志模式,文件系統(tǒng)的日志區(qū)域雖然也記錄將寫入磁盤的新文件的Inode、Block bitmap、Inode bitmap等索引信息。但是和ordered日志模式不同的是,這些日志信息記錄過程和文件數(shù)據(jù)的寫入過程沒有先后關(guān)聯(lián),并且也不存在“提交”的概念。當(dāng)文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序也不會(huì)按照日志區(qū)域的數(shù)據(jù)狀態(tài)進(jìn)行一致性修復(fù)。writeback日志模式在大多數(shù)情況下能夠提供最佳的Ext3/Ext4文件系統(tǒng)性能,因?yàn)槿罩竟δ軒缀跏顷P(guān)閉的。
從以上三種Ext3文件系統(tǒng)日志模式的簡述中,可以發(fā)現(xiàn)的Ext3日志并不保證數(shù)據(jù)不丟失。實(shí)際上保證數(shù)據(jù)不丟失并不是Ext3日志的目標(biāo),而保證數(shù)據(jù)一致性才是Ext3日志的主要目標(biāo)。為了達(dá)到這個(gè)目標(biāo),日志數(shù)據(jù)甚至?xí)鲃?dòng)丟棄無法復(fù)原的副本數(shù)據(jù)。
設(shè)置文件系統(tǒng)日志級別 本小節(jié)介紹如何查看和設(shè)置Ext3/Ext4文件系統(tǒng)的日志模式。首先為了確定當(dāng)前文件系統(tǒng)是否開啟了日志模式,可以使用dumpe2fs命令進(jìn)行查看:
# dumpe2fs /dev/sdb2
dumpe2fs 1.41.12 (17-May-2010)
Filesystem volume name: ? <none>
Last mounted on: ? ? ? ? ?<not available>
Filesystem UUID: ? ? ? ? ?0e94b563-8348-4056-8770-67fa34e2b903
Filesystem magic number: ?0xEF53
Filesystem revision #: ? ?1 (dynamic)
Filesystem features: ? ? ?has_journal ext_attr resize_inode dir_index filetype
......
Journal backup: ? ? ? ? ? inode blocks
Journal features: ? ? ? ? (none)
日志大小: ? ? ? ? ? ? 128M
Journal length: ? ? ? ? ? 32768
Journal sequence: ? ? ? ? 0x00000001
Journal start: ? ? ? ? ? ?0
......
以下的block group信息可以忽略
可以看到Filesystem features選項(xiàng)中有一個(gè)has_journal關(guān)鍵信息標(biāo)識(shí),這表示當(dāng)前文件系統(tǒng)已經(jīng)開啟了日志功能。如果沒有看到這個(gè)標(biāo)記,則說明文件系統(tǒng)本身還沒有開啟日志功能——這種情況下Ext3文件系統(tǒng)就和Ext2文件系統(tǒng)沒有太大區(qū)別了。
以下命令可以開啟Ext3/Ext4文件系統(tǒng)的日志功能:
# tune2fs -O has_journal /dev/sdb2
tune2fs 1.41.12 (17-May-2010)
Creating journal inode: done
以下命令可以關(guān)閉Ext3/Ext4文件系統(tǒng)的日志功能:
# tune2fs -O ^has_journal /dev/sdb2
tune2fs 1.41.12 (17-May-2010)
但必須注意這并不表示指定了具體的日志模式,在開啟了文件系統(tǒng)日志功能的情況下讀者可以在使用mount進(jìn)行具體掛載時(shí)指定日志模式。如下所示:
mount -o data=journal /dev/sdb2 /mnt/hgfs/
以上命令的data參數(shù)部分可以換成ordered、writeback和journal,代表文件系統(tǒng)支持的三種日志模式。設(shè)置完成后文件一同也完成了掛載。但是怎么檢查日志模式設(shè)置是否成功呢?讀者可以通過dmesg命令查看Linux系統(tǒng)的內(nèi)核日志,在日志的最后一行會(huì)有最近一次的掛載信息,類似如下:
# dmesg
......
EXT3-fs (sdb2): using internal journal
EXT3-fs (sdb2): mounted filesystem with journal data mode
SELinux: initialized (dev sdb2, type ext3), uses xattr
可以看到內(nèi)核日志信息的最后一行信息說明最近完成的內(nèi)核變動(dòng)操作,是按照journal日志模式掛載sdb2分區(qū)。當(dāng)然內(nèi)核日志信息包含了很多無用的信息,讀者還可以通過以下命令索引出需要查看的信息:
# dmesg | grep -B 1 "mounted filesystem"
......
sd 2:0:0:0: [sda] Attached SCSI disk
EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts:
--
Microcode Update Driver: v2.00 <[email]tigran@aivazian.fsnet.co.uk[/email]>, Peter Oruba
EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts:
--
EXT3-fs (sdb2): using internal journal
EXT3-fs (sdb2): mounted filesystem with journal data mode
......
當(dāng)然最終我們還是要實(shí)現(xiàn)磁盤的永久掛載,這是就需要更改Linux操作系統(tǒng)中的/etc/fstab文件了。如果讀者使用的是文件系統(tǒng)默認(rèn)的ordered日志模式,則不需要在/etc/fstab文件中進(jìn)行額外的設(shè)置。但如果不是這樣的話,讀者在設(shè)置/etc/fstab文件時(shí),就要在其中的options列說明文件系統(tǒng)使用的日志模式。類似如下所示:
# vim /etc/fstab
......
/dev/sdb2 ? ? ? /mnt/hgfs ? ? ? ext3 ? ? ? ?data=journal ? ? ? ?0 0
......
