淺析Linux文件系統

http://www.sohu.com/a/211162589_467784

一、文件系統層次分析

由上而下主要分爲用戶層、VFS層、文件系統層、緩存層、塊設備層、磁盤驅動層、磁盤物理層

用戶層

最上面用戶層就是我們日常使用的各種程序,需要的接口主要是文件的創建、刪除、打開、關閉、寫、讀等。

VFS層

我們知道Linux分爲用戶態和內核態,用戶態請求硬件資源需要調用System Call通過內核態去實現。用戶的這些文件相關操作都有對應的System Call函數接口,接口調用VFS對應的函數。

文件系統層

不同的文件系統實現了VFS的這些函數,通過指針註冊到VFS裏面。所以,用戶的操作通過VFS轉到各種文件系統。文件系統把文件讀寫命令轉化爲對磁盤LBA的操作,起了一個翻譯和磁盤管理的作用。

緩存層

文件系統底下有緩存,Page Cache,加速性能。對磁盤LBA的寫數據緩存到這裏。

塊設備層

塊設備接口Block Device是用來訪問磁盤LBA的層級,讀寫命令組合之後插入到命令隊列,磁盤的驅動從隊列讀命令執行。Linux設計了電梯算法等對很多LBA的讀寫進行優化排序,儘量把連續地址放在一起。

磁盤驅動層

磁盤的驅動程序把對LBA的讀寫命令轉化爲各自的協議,比如變成ATA命令,SCSI命令,或者是自己硬件可以識別的自定義命令,發送給磁盤控制器。Host Based SSD甚至在塊設備層和磁盤驅動層實現了FTL,變成對Flash芯片的操作。

磁盤物理層

讀寫物理數據到磁盤介質。

二、文件系統結構與工作原理

我們都知道,windows文件系統主要有fat、ntfs等,而linux文件系統則種類繁多,主要有VFS做了一個軟件抽象層,向上提供文件操作接口,向下提供標準接口供不同文件系統對接,下面主要就以EXT4文件系統爲例,講解文件系統結構與工作原理:

上面兩個圖大體呈現了ext4文件系統的結構,從中也相信能夠初步的領悟到文件系統讀寫的邏輯過程。下面對上圖裏邊的構成元素做個簡單的講解:

引導塊

爲磁盤分區的第一個塊,記錄文件系統分區的一些信息,引導加載當前分區的程序和數據被保存在這個塊中。一般佔用2KB。

超級塊

超級塊用於存儲文件系統全局的配置參數(譬如:塊大小,總的塊數和inode數)和動態信息(譬如:當前空閒塊數和inode數),其處於文件系統開始位置的1k處,所佔大小爲1k。

爲了系統的健壯性,最初每個塊組都有超級塊和組描述符表(以下將用GDT)的一個拷貝,但是當文件系統很大時,這樣浪費了很多塊(尤其是GDT佔用的塊多),後來採用了一種稀疏的方式來存儲這些拷貝,只有塊組號是3, 5 ,7的冪的塊組(譬如說1,3,5,7,9,25,49…)才備份這個拷貝。

通常情況下,只有主拷貝(第0塊塊組)的超級塊信息被文件系統使用,其它拷貝只有在主拷貝被破壞的情況下才使用。

塊組描述符

GDT用於存儲塊組描述符,其佔用一個或者多個數據塊,具體取決於文件系統的大小。

它主要包含塊位圖,inode位圖和inode表位置,當前空閒塊數,inode數以及使用的目錄數(用於平衡各個塊組目錄數),具體定義可以參見ext3_fs.h文件中struct ext3_group_desc。

每個塊組都對應這樣一個描述符,目前該結構佔用32個字節,因此對於塊大小爲4k的文件系統來說,每個塊可以存儲128個塊組描述符。由於GDT對於定位文件系統的元數據非常重要,因此和超級塊一樣,也對其進行了備份。GDT在每個塊組(如果有備份)中內容都是一樣的,其所佔塊數也是相同的。

從上面的介紹可以看出塊組中的元數據譬如塊位圖,inode位圖,inode表其位置不是固定的,當然默認情況下,文件系統在創建時其位置在每個塊組中都是一樣的,如圖2所示(假設按照稀疏方式存儲,且n不是3,5,7的冪)

塊組

每個塊組包含一個塊位圖塊,一個 inode 位圖塊,一個或多個塊用於描述 inode 表和用於存儲文件數據的數據塊,除此之外,還有可能包含超級塊和所有塊組描述符表(取決於塊組號和文件系統創建時使用的參數)。下面將對這些元數據作一些簡要介紹。

塊位圖

塊位圖用於描述該塊組所管理的塊的分配狀態。如果某個塊對應的位未置位,那麼代表該塊未分配,可以用於存儲數據;否則,代表該塊已經用於存儲數據或者該塊不能夠使用(譬如該塊物理上不存在)。由於塊位圖僅佔一個塊,因此這也就決定了塊組的大小。

Inode位圖

Inode位圖用於描述該塊組所管理的inode的分配狀態。我們知道inode是用於描述文件的元數據,每個inode對應文件系統中唯一的一個號,如果inode位圖中相應位置位,那麼代表該inode已經分配出去;否則可以使用。由於其僅佔用一個塊,因此這也限制了一個塊組中所能夠使用的最大inode數量。

Inode表

Inode表用於存儲inode信息。它佔用一個或多個塊(爲了有效的利用空間,多個inode存儲在一個塊中),其大小取決於文件系統創建時的參數,由於inode位圖的限制,決定了其最大所佔用的空間。

以上這幾個構成元素所處的磁盤塊成爲文件系統的元數據塊,剩餘的部分則用來存儲真正的文件內容,稱爲數據塊,而數據塊其實也包含數據和目錄。

瞭解了文件系統的結構後,接下來我們來看看操作系統是如何讀取一個文件的:

大體過程如下:

1、根據文件所在目錄的inode信息,找到目錄文件對應數據塊

2、根據文件名從數據塊中找到對應的inode節點信息

3、從文件inode節點信息中找到文件內容所在數據塊塊號

4、讀取數據塊內容

到這裏,相信很多人會有一個疑問,我們知道一個文件只有一個Inode節點來存放它的屬性信息,那麼你可能會想如果一個大文件,那它的block一定是多個的,且可能不連續的,那麼inode怎麼來表示呢,下面的圖告訴你答案:

也就是說,如果文件內容太大,對應數據塊數量過多,inode節點本身提供的存儲空間不夠,會使用其他的間接數據塊來存儲數據塊位置信息,最多可以有三級尋址結構。

到這裏,應該都已經非常清楚文件讀取的過程了,那麼下面再拋出兩個疑問:

1、文件的拷貝、剪切的底層過程是怎樣的?

2、軟連接和硬連接分別是如何實現的?

下面來結合stat命令動手操作一下,便知真相:

1)拷貝文件:創建一個新的inode節點,並且拷貝數據塊內容

2)剪切文件:同個分區裏邊mv,inode節點不變,只是更新目錄文件對應數據塊裏邊的文件名和inode對應關係;跨分區mv,則跟拷貝一個道理,需要創建新的inode,因爲inode節點不同分區是不能共享的。

3)軟連接:創建軟連接會創建一個新的inode節點,其對應數據塊內容存儲所鏈接的文件名信息,這樣原文件即便刪除了,重新建立一個同名的文件,軟連接依然能夠生效。

4)硬鏈接:創建硬鏈接,並不會新建inode節點,只是links加1,還有再目錄文件對應數據塊上增加一條文件名和inode對應關係記錄;只有將硬鏈接和原文件都刪除之後,文件纔會真正刪除,即links爲0才真正刪除。

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