Linux的Ext2文件系統

一、簡介

1、通常所做的磁盤分區格式化,爲什麼要對磁盤分區進行格式化?

那就是因爲每種操作系統所設置的文件屬性/權限等數據並不相同,爲了存放這些文件所需的數據,那麼就需要將分區進行格式化,以成爲操作系統能夠利用的文件系統格式。

2、一個文件系統就是一個分區嗎?

在早期,一個分區只能被格式化爲一個文件系統,所以一個文件系統就是一個分區。但是由於新技術的到來,可以將一個分區格式化爲多個文件系統,也可以將多個分區合成一個文件系統,所以說一個文件系統就是一個分區是不完全正確的。在格式化時就不能說成是針對分區來格式化了,通常可以稱呼一個可被掛載的數據爲一個文件系統,而不是將一個分區稱爲一個文件系統。

3、Linux正規文件系統Ext2:Linux Second Extended File System,Ext2fs。

二、Linux的Ext2文件系統的運作與其它文件系統的比較

1、Linux的Ext2文件系統是如何運作的?

一個文件除了實際的文件數據以外,通常還含有其它很多的文件屬性。Linux的Ext2文件系統通常會將這兩部分的數據分別存放在不同的。分別如下:

  • block:實際記錄文件的內容。若文件太大可能會佔用多個block。有編號。
  • inode:記錄文件的屬性,一個文件佔用一個inode,同時還記錄此文件的內容所在的那些block的號碼。有編號。
  • super block:記錄此文件系統的整體信息,包括inode/block的總量、使用量、剩餘量,以及文件系統的格式與相關信息等。

由以上內容就可以得知,當知道一個文件的inode時,就可以知道這個文件所放置數據的那些block的號碼,所以就能夠讀出該文件的數據,如下圖所示,上面兩排表示inode,下面三排表示block,文件系統一開始就將inode和block規劃好了,除非重新格式化或者利用resize2fs等命令更改文件系統大小,否則inode和block固定後就不再變動。圖中表示一個文件佔用的是4號inode,則該文件的一些屬性就是存在於4號inode中的,且箭頭指向就是表示該inode記錄了文件數據的實際放置點爲箭頭指向的這幾個block號碼中。當讀取該文件數據時,操作系統就可以據此來排列磁盤的閱讀順序,可以一下子將4個block的內容讀取出來。我們把這種數據訪問方式的文件系統稱爲索引式文件系統

2、其他文件系統

比如在Windows系統中有一個文件系統叫做FAT,該文件系統並不存在inode,而採用的方式是實際存放數據的block指向下一個存放數據的block,所以該文件系統不可以將一個文件的所有block在一開始就全部讀取出來,它必須要一個一個地將block讀出來,纔會知道下一個block。如下圖。而且如果一個文件數據寫入的block分散得過於厲害時,磁盤磁頭將無法在磁盤轉一圈就讀到所有的數據,因此磁盤可能就會多轉幾圈才能完整地讀取該文件的數據,所以就有了所謂的“碎片整理”來將同一個文件所屬的block匯合在一起以便使數據的讀取更容易。Linux的Ext2文件系統由於是索引式文件系統,基本上不需要碎片整理,但是如果文件系統使用太久,經常刪除/編輯/新增文件時,還是可能會造成文件數據過於離散的問題,此時或許還是需要進行碎片整理。

三、Ext2文件系統的塊組

1、如果文件系統很大時,則inode和block的數量也會很大,將它們放在一起則不容易管理,所以Ext2文件系統在格式化時基本上是區分多個塊租的,每個塊組都有獨立的inode/block/super block系統。整個Ext2文件系統格式化後如下圖所示。注意:在整體的規劃當中,文件系統最前面有一個啓動扇區,它可以安裝引導裝載程序。

2、data block(數據塊)

data block就是前面說的用來存放文件實際數據內容的block。在Ext2文件系統中支持的block大小有1KB、2KB和4KB三種大小,且在格式化時block的大小就固定了。注意:採用不同大小的block,會導致該文件系統能夠支持的最大磁盤容量與最大單一文件容量並不相同,詳細分析見後面的inode table。除了這些特性之外,block還有其它一些特性,如下:

  • 原則上,block的大小和數量在格式化後就不能再改變了,除非重新格式化。
  • 每個block內最多隻能放置一個文件的數據。
  • 如果文件大於block的大小,則一個文件會佔用多個block。
  • 如果文件小於block的大小,則該block的剩餘空間就不能夠再被使用了。

如上最後一個特性,該特性會導致磁盤空間的浪費問題,比如Ext2文件系統採用的block大小爲4KB,該文件系統中有10000個大小爲50byte的小文件,在這種情況下,由於每個block內最多隻能放置一個文件的數據,所以存放這10000個文件的每個block浪費的大小爲(4KB * 1024)byte - 50byte = 4046byte,所以10000個文件總共就會浪費4046byte * 10000,大約38.6M大小的磁盤空間就被浪費了,而這10000個文件真正的總大小才50byte * 10000,還不到1MB。所以較大的block可能會造成磁盤空間浪費的問題,但是如果block過小的話,大型文件就會佔用較多的block,而inode也要記錄更多的block號碼,這也可能會導致文件系統不良的讀寫性能,所以使用多大的block,應該看系統預計使用的情況來決定。

3、inode table(inode表格)

這個東西也就是前面說的inode,inode的特性如下:

  • 記錄該文件的訪問模式(read/write/excute)。
  • 記錄該文件的所有者與組。
  • 記錄該文件的大小。
  • 記錄該文件創建或狀態改變的時間(ctime)。
  • 記錄該文件最近一次的讀取事件(atime)。
  • 記錄該文件最近修改的時間(mtime)。
  • 定義文件特性的標誌,如SetUID。
  • 記錄該文件真正內容的指向。
  • inode的數量和大小在格式化時已經固定了。
  • 每個inode的大小均固定爲128byte。
  • 每個文件都僅僅會佔用一個inode而已。
  • 文件系統能夠創建的文件數量與inode的數量有關。
  • inode記錄一個block號碼需要4byte。

正因爲inode記錄了文件的這些屬性,所以當系統讀取文件時是先找到文件的inode,並分析inode記錄的權限與用戶是否符合,若符合才能讀取文件的內容,也就是block的內容。

如果文件的內容很大,那麼可能會花費很多的block,但是inode的大小才128byte,那麼如何記錄數量很多的block號碼,所以Ext2文件系統將inode記錄block號碼的區域定義爲12個直接、一個間接、一個雙間接和一個三間接記錄區。inode的結構如下圖。其中的12個直接就是直接保存了存放實際數據的block的號碼;而一個間接就是再拿一個block來當作記錄保存了實際數據的block號碼的記錄區;雙間接就是第一個block僅指出下一個記錄編號的block在那裏,實際記錄在第二個block中,三間接就是利用第三層block來記錄編號。

有了12個直接、一個間接、一個雙間接和一個三間接記錄區,那麼inode能記錄多少個block呢?以1KB的block來說明。計算如下:

  • 12個直接:由於是直接,所以能記錄12個block編號。
  • 一個間接:由於間接是拿一個block來記錄存放了實際數據的block的編號,這裏的block大小爲1KB,而記錄一個block需要花掉4byte,所以這個間接能記錄(1KB * 1024)byte / 4byte = 256,所以該間接能記錄256個block編號。
  • 一個雙間接:雙間接是使用第二層block來記錄存放了實際數據的block的編號,由上面的間接可以發現第一層能記錄256個block,這256個block在雙間接中就是處於第二層,所以它們每個又能記錄256個block編號,所以雙間接能記錄256 * 256 = 65535個block編號。
  • 一個三間接:由上面的推斷可以斷定在三間接中第一層block能記錄256個第二層,每個第二層又能256個第三層,每個第三層的block又能記錄256個block編號,所以三間接能記錄256 * 256 * 256 = 16777216個編號。
  • 總額:將12個直接、一個間接、一個雙間接和一個三間接能記錄的block編號的個數相加,即12 + 256 +65535 + 16777216 = 16843019,所以它們總共能記錄16843019個block編號,而由於這裏的每個block大小爲1KB,所以總共的大小爲16843019KB,即大約爲16G,所以當文件系統將block格式化爲1KB大小時,能夠容納的單一文件的最大容量爲16G。
  • 注意:以上的計算方法不能用在2KB和4KB的block大小的計算中,因爲2KB的block將會受到Ext2文件系統本身的限制。

4、super block(超級塊)

super block主要記錄的信息與特性如下:

  • block與inode的總量。
  • 未使用與已使用的inode/block數量。
  • block與inode的大小。
  • 文件系統的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤的時間等文件系統相關信息。
  • 一個valid bit數值,若此文件系統已被掛載,則valid bit爲0,若未掛載則爲1。
  • 一般情況下,super block大小爲1024byte。
  • 每個block group都可能含有super block,但是一個文件系統應該僅有一個super block而已,事實上,除了第一個block group內會含有super block之外,其它block group不一定含有super block,而若含有則該super block主要是作爲第一個block group內的super block的備份。

5、文件系統描述

該區段可以描述每個block group的開始與結束的block號碼,以及說明每個區段(super block、bitmap、indoemap、data block)分別介於哪一個block號碼之間。

6、塊對應表(block bitmap)

當要添加新文件時,則要用block來存放其內容,那麼從塊對應表中就可以知道哪些block是空的,就可以找到空的block來存放新文件的數據;同樣,當刪除一個文件時,文件原本佔用的block號碼就要釋放出來,此時在塊對應表中相對應到該block號碼的標誌就要修改爲“未使用”。

7、inode對應表(inode bitmap)

與block對應表功能類似,只不過它記錄的是使用與未使用的inode號碼。

四、使用dumpe2fs命令來查看文件系統的信息

 使用“dumpe2fs 設備文件名”可以查看文件系統的相關信息,如下圖是使用該命令(dumpe2fs /dev/sda2)查看我的/目錄所掛載的設備的文件系統的部分信息,可以發現block group內的所有信息都是以block的號碼來表示的,各部分數據都與block有關。注意其中畫紅色方框的上部分,這部分表示inode table分佈在643~1666的block號碼中,總共有1666 - 643 + 1(643本身) = 1024個block花在inode table上,我這個文件系統採用的block大小爲4KB,所以inode的數量共有(1024 * 4KB * 1024)byte / 128byte = 32768(每個inode爲128byte大小)個inode在block group0中。正好與下面一個紅色方框中的數字相符。

五、文件系統與目錄樹的關係

1、在Linux中不管是一般文件還是目錄文件都會佔用一個inode,其可依據文件(一般文件和目錄統稱文件)內容的大小來分配一些block給該文件使用。只不過一般文件是實際記錄數據內容,而目錄文件的內容是記錄該目錄中的文件名。

2、目錄

當新建一個目錄時,系統會分配一個inode與至少一個block給該目錄。由上面的介紹可知,inode用於記錄該目錄的權限與屬性,且記錄分配到的那塊block號碼;至於分配給目錄的block則是記錄在這個目錄下的文件名與該文件名佔用的inode號碼數據。目錄所佔用的block記錄的信息如下圖。

3、目錄大小、目錄內文件大小與block大小的關係

讓我們看看根目錄所掛載的設備的文件系統採用的block的大小是多大,如下圖,可以發現block爲4KB大小。

那麼,讓我們在/tmp目錄下新建一個目錄叫做test,然後我在test目錄下放入了一個大小約爲31MB左右的壓縮包,如下圖:

注意觀察,test目錄的大小爲4096byte,而該目錄下的nexus-2.2-01-bundle.zip文件大小約爲31MB左右,可以發現目錄的大小並不是該目錄內所有文件大小的總和,與目錄內文件大小無關。那麼該目錄大小爲4096是如何來的啊?因爲上上圖可以發現根目錄所掛載的設備的文件系統的block的大小爲4096,因爲該目錄並不複雜,只佔用了一個block,所以該目錄大小爲4096。如果一個目錄的內容很複雜,文件數太多,那麼該目錄可能會佔用多個block,那麼目錄的大小就會是block大小的整數倍,如下圖:其中的/sbin目錄的大小爲12288,就是大小爲4096byte的block的3倍,該目錄就是佔用了3個大小爲4096byte的block。那麼爲什麼其中還有大小爲1024byte的/boot目錄和大小爲0的/proc目錄呢?那是因爲/boot爲獨立的分區,和/目錄不是同一個分區,/boot目錄所掛載的分區的文件系統採用的block大小爲1KB。而/proc目錄是不佔用硬盤容量的,它放置的數據都是在內存中的。

4、文件

當新建一個一般文件時,會分配一個inode和相對於該文件大小的block數量給該文件。比如文件系統的block爲4KB,要新建一個100KB大小的文件,那麼將會分配一個inode和25個block給該文件。注意:由於inode只有12個直接,所以還需要多一個block來作爲塊號碼的記錄。

5、目錄樹的讀取

從上面目錄的介紹中,能知道inode本身不記錄文件名,文件名的記錄是在目錄的block中。新增/刪除/重命名文件名等操作與目錄的w權限有關就是因此原因。所以要讀取某個文件時,就會經過該文件所在的目錄的inode與block,然後才能找到該文件的inode號碼,最終才能讀到該文件的block中的數據。

由於目錄樹是由根目錄開始,所以系統可以通過掛載的信息找到掛載點的inode號碼(通常一個文件系統的最頂層inode號碼會由2號開始),然後就能得到根目錄的inode內容,並依據該inode讀取根目錄的block內的文件名數據,再一層一層地往下讀就可以讀到正確的文件名。比如要讀取/etc/passwd文件,讀取流程如下:

  • /的inode:通過掛載點的信息找到/dev/sda2的inode號碼爲2的根目錄inode,且根目錄的inode記錄的權限讓root帳號可以讀取該inode指向的block的內容。
  • /的block:經過上個步驟可以取得根目錄inode所記錄的block的號碼,所以可以找到etc/目錄的inode號碼(1835009)。
  • etc/的inode:讀取1835009號inode得知root具有rwx權限,所以可以讀取etc/的inode所記錄的block內容。
  • etc/的block:經過上個步驟取得etc/目錄的inode記錄的block號碼,並找到passwd文件的inode號碼(1837426)。
  • passwd的inode:讀取1837426號的inode得知root帳號具有rw的權限,所以可以讀取passwd文件的inode所記錄的block的內容。
  • passwd的block:將該block內容讀取出來。

六、文件系統大小與磁盤讀取性能

1、如果文件系統很大時,由於硬盤上面的數據是經常變動的,所以整個文件系統上面的文件通常無法連續寫在一起,即block號碼不會連續,而是填入式的將數據填入空閒的block中,如果文件寫入的block很分散,可能就會造成文件數據離散的問題。雖然ext2的每個inode記錄了block號碼,數據可以一次性讀取,但是如果文件分散過於厲害,讀取的效率就可能會很低,因爲磁頭還是得要在整個文件系統中頻繁的讀取。解決辦法爲:將整個文件系統內的數據全部複製出來,將該文件系統重新格式化,再將數據複製回去。

2、如果文件系統很大,當一個文件分別記錄在文件系統的最前面和最後面的block號碼中,此時會造成硬盤的機械手臂移動幅度過大,而造成數據讀取性能低。且磁頭在搜尋整個文件系統時也會花費很多的時間。

3、所以分區的規劃並不是越大越好,要針對主機的用途來進規劃。

七、Ext2/Ext3文件的訪問與日誌文件系統的功能

1、Ext2文件系統對新建文件或目錄的過程如下:

  • 先確定用戶對於要添加的文件所在的目錄是否具有w與x的權限,若有的話才能進行添加。
  • 根據inode bitmap找到空閒的inode號碼,並將文件的權限/屬性寫入。
  • 根據block bitmap找到空閒的block號碼,並將實際的數據寫入block中,且更新inode的block指向數據。
  • 將以上寫入的inode和block數據同步更新到inode bitmap和block bitmap,並更新super block的內容。

2、就以上新建文件的過程,如果在寫入inode和block後發生了錯誤導致系統不能同步更新inode bitmap和block bitmap,那麼就會產生數據不一致的情況,在早起的Ext2文件系統中,如果發生了這個問題,那麼系統在重啓時,就會通過super block中記錄的valid bit與文件系統的state(clean與否)等狀態來判斷是否強制進行數據一致性的檢查。這樣的檢查很費時,因爲要針block bitmap、inode bitmap、super block等中間數據與實際數據存放區來進行比對,要搜尋整個文件系統,

3、日誌文件系統

爲了解決文件系統數據不一致的情況,可以在文件系統中規劃一個塊,該塊專門記錄寫入或修改文件時的步驟,具體如下:

  • 預備:當系統要寫入一個文件時,會先在日誌記錄塊中記錄某個文件準備要寫入的信息。
  • 實際寫入:開始寫入文件的權限與數據;然後開始更新block bitmap、inode bitmap、super block等中間數據。
  • 結束:完成數據與中間數據的更新後,在日誌記錄塊中完成該文件的記錄。

這樣做的好處是,如果在數據的記錄過程中發生了問題導致數據不一致,系統只需要去檢查日誌記錄塊就可以知道哪個文件發生了問題,針對該問題來做一致性的檢查即可,而不必針對整個文件系統去檢查。

Ext2文件系統要達到這樣的功能是通過Ext3文件系統來實現的,Ext3是Ext2的升級版,且可向下兼容Ext2。

八、Linux文件系統的操作

1、Linux的異步處理

當系統加載一個文件到內存後,如果該文件沒有被改動過,則在內存區段的文件數據會被設置爲clean的。但若內存中的文件數據被更改過了,此時該內存中的數據會被設置爲Dirty,此時所有的操作都還在內存中進行,並沒有寫入到磁盤中,系統會不定時地將內存中設置爲Dirty的數據寫回磁盤,以保持磁盤與內容數據的一致性。也可以使用sync命令來手動強迫寫入磁盤。

2、Linux文件系統與內存的關係

  • 系統會將常用的文件數據放置到主存儲器的緩衝區,以加速文件系統的讀/寫。所以Linux的物理內存最後都會被用光。
  • 若正常關機時,關機命令會主動調用sync命令來將內容的數據回寫入磁盤內。
  • 若不正常關機時,由於數據尚未寫入磁盤內,因此重啓後可能會花很多的時間在進行磁盤檢驗,甚至可能導致文件系統的損毀(非磁盤損毀)。

九、掛載點的意義

1、將文件系統與目錄樹結合的操作稱爲掛載。

2、掛載點一定是目錄,該目錄爲進入該文件系統的入口。所以一個文件系統必須要掛載到目錄樹的某個目錄後,才能夠使用該文件系統。

3、在Linux中一切都是文件,那麼磁盤也是文件,有一個文件名,一個分區也是一個文件,有文件名;從上面的目錄樹介紹中我們可以知道文件名是保存在目錄的block中的,那麼要使用一個文件,就要知道一個文件所在的目錄,因爲根據該目錄才能找到目錄的block,才能找到對應的文件名,所以文件系統需要掛載到目錄嘛。

4、如下圖所示,在我的系統中有三個分區(除去最後一個tmpfs,這裏一個分區就是一個文件系統),對應三個掛載點,而查看每個掛載點的inode號碼時,它們的inode均爲2(每個文件系統都有獨立的inode、block與super block等信息,且文件系統最頂層的目錄的inode一般爲2號),且每一行的文件屬性不同,三個掛載點也均不同,所以可以發現/、/boot、/home爲三個不同的文件系統。

4、“.”表示當前目錄,而“..”表示當前目錄的上一層目錄;但是在根目錄(/)的“.”與“..”是相同的東西,爲什麼呢?如下圖,由於掛載點均爲/,所以這三個目錄均在同一個文件系統內,且這三個目錄的inode均爲2,所以這三個目錄都指向同一個inode號碼,而從inode的介紹中我們知道同一個文件系統的某個inode只會對應到一個文件內容而已,因爲一個文件佔用一個inode的原因,所以這三個目錄的內容也就是一樣的,所以根目錄的上層(/..)就是它自己。

十、Linux VFS

1、整個Linux系統是通過一個名爲Virtual Filesystem Switch(虛擬文件系統,VFS)的內核功能去讀取文件系統的,即整個Linux認識的文件系統其實都是VFS在進行管理的,用戶並不需要知道每個分區上面的文件系統是什麼,VFS會做好讀取的操作。比如假設/使用的是/dev/hda21,用的是ext3文件系統,而/home使用的是/dev/hda2,reiserfs文件系統,當讀取/home/jgao/.bashrc文件時,我們都不需要指定要用什麼文件系統的模塊來讀取,VFS會幫我們管理。VFS文件系統示意圖如下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章