來點綠色放松一下眼睛吧 :)

文件系統是對文件和目錄的組織集合。
一 設備文件
設備文件和系統的某個設備相對應。
設備驅動程序
- 處理設備的所有IO請求。
- 提供了一致的API接口,對應於系統調用的open, close, read, write, mmap以及ioctl,屏蔽了底層設備的差異。
設備的類型
- 字符型設備:基於每個字符來處理請求,例如終端和鼠標、鍵盤。
- 塊設備:按數據塊處理請求,通常數據塊是512字節的整數倍。例如硬盤和磁帶。
設備ID
- 每個設備文件都有主、輔設備文件ID。主文件ID標識一般的設備等級,內核會根據主ID查找與該類設備對應的設備驅動程序。
- 輔ID能夠在一般等級中唯一標識特定設備。
- 文件的inode中記錄了主輔ID
二 磁盤和分區
2.1 磁盤驅動器
磁盤驅動器是一種機械裝置,由一個或多個高速旋轉的盤片組成。通過在磁盤上快速移動讀寫磁頭,便可獲取/修改磁盤表面的磁性編碼信息。
其結構見下圖。


磁道:磁盤表面的信息存儲在稱為磁道的一組同心圓上。
扇區:磁道被劃分為若干扇區。
物理塊:扇區包含一系列物理塊,物理塊的容量一般為512字節,代表了驅動器可以讀寫的最小信息單位。
尋道時間:讀寫磁盤信息,首先,磁頭要移動到相應磁道,這段時間叫做尋道時間。
旋轉延遲:然後,驅動器要等待相應的扇區旋轉到磁頭下。
傳輸時間:最後,從所請求的塊上傳輸數據。
執行上述操作所耗費的時間總量通常以毫秒為單位。
2.1 磁盤分區
分區:可將每塊磁盤換分成一個或多個不重疊的分區。內核則將每個分區視為位於/dev路徑下的單獨設備。
磁盤分區可容納任何類型的信息,通常包括:
- 文件系統:用來存放常規文件
- 數據區域:可做為裸設備對其進行訪問,一些數據庫管理系統會這樣使用。
- 交換區域:供內核的內存管理之用。
可使用Linux專有文件/proc/swaps來查看系統中當前已激活交換區域的信息,其中包括每個交換區域的大小,以及在用交換區域的個數。
三 文件系統
文件系統是對常規文件和目錄的組織集合。
Linux的強項之一是支持種類繁多的文件系統。
以ext2為例來介紹文件系統。
3.1 文件系統結構
邏輯塊:在文件系統中,用來分配空間的基本單位是邏輯塊,也就是文件系統所在物理設備上若干連續的物理塊。在ext2文件系統上,邏輯塊的大小為1024、2048或4096。
磁盤分區和文件系統之間的關系如下圖所示

文件系統由以下幾個部分組成:
- 引導塊:總是作為文件系統的首塊。引導塊不為文件系統所用,只是包含用來引導操作系統的信息。
- 超級塊:緊隨引導塊之後的一個獨立塊,包含與文件系統相關的參數信息,包括:
- i節點表容量
- 文件系統中邏輯塊的大小
- 以邏輯塊計,文件系統的大小
- i節點表:文件系統中的每個文件或目錄在i節點表中都對應著唯一一條記錄。這條記錄登記了和文件相關的各種信息。
- 數據塊:文件系統的大部分空間都用於存放數據,以構成駐留於文件系統之上的文件和目錄。
3.2 i節點
i節點維護的信息如下
- 文件類型
- 文件屬主
- 文件屬組
- 3類用戶的訪問權限
- 3個時間戳:對文件的最後訪問時間、文件的最後修改時間、文件狀態的最後改變時間
- 指向文件的硬連接數量
- 文件的大小,以字節為單位
- 實際分配給文件的數據塊,以512字節為單位
- 指向文件數據塊的大小
ext2中的i節點和數據塊指針
文件的數據塊不一定連續,為了定位文件數據塊,inode維護了一組指針,如下圖所示:

在ext2中,每個inode包含15個指針,其中
- 前12個指針指向前12個數據塊在文件系統中的位置。
- 第13個指針是一個一重間接指針
- 第14個指針是一個二重間接指針
- 第15個指針是一個三重間接指針
這樣設計的意圖是:
- inode結構固定大小固定,並支持任意大小的文件
- 可以不連續地存儲文件,並支持lseek隨機訪問,內核只需要計算所要遵循的指針
- 對於有大量小文件的系統中,可以對數據進行快速訪問,一次搜索就可以訪問。
四 虛擬文件系統(VFS)
Linux所支持的各種文件系統,其實現細節均不相同。虛擬文件系統是一種內核特性,通過為文件系統操作創建抽象層來解決各種文件系統之間的差異問題。

原理:
- VFS針對文件系統定義了一套通用接口,所有與文件交互的程序都會按照這一接口來進行操作。
- 每種文件系統都會提供VFS接口的實現。
這樣一來,程序只需要理解VFS接口,而無需過問具體文件系統的實現細節。
五 日志文件系統
如果系統突然崩潰,對文件的更新的只完成了一半,文件系統元數據也將處於不一致狀態。
而系統對文件系統進行一致性檢查需要遍歷整個文件系統,這是一個非常耗時的操作。
日志文件系統就是為了解決這個問題。具體做法是
- 在實際更新元數據之前,日志文件系統會將這些更新操作記錄於專用的磁盤日志文件中。
- 對元數據更新的操作記錄是以事務的方式進行的,這樣確保總是將文件元數據事務作為一個完整單元來提交。
需要注意的是,通常日志文件系統知會確保元數據的一致性,不會記錄文件數據。因此,一旦系統崩潰,可能會造成數據丟失。
六 單根目錄層級和掛載點
Linux上的所有文件系統中的文件都位於單根目錄樹下,其他文件系統都掛載在根目錄下。
掛在命令:
mount device directory
?
下面通過實例來說明掛載後的文件系統的層級關系。
不帶任何參數來執行mount命令,可以列出當前已掛載的文件系統。

掛載點和設備的映射關系如下

七 虛擬內存文件系統:tmpfs
Linux支持駐留於內存中的虛擬文件系統,對於應用程序來說,此類文件系統看起來與任何其他文件系統別無二致,不過二者的重要的差別是:
- 由於不涉及磁盤訪問,虛擬文件系統的文件操作速度極快
- 該文件系統不僅可以使用RAM,而且在RAM資源耗盡的情況下,還會利用交換空間
- 默認情況下,允許tmpfs文件系統的大小提高至RAM容量的一半
- 一旦寫在tmpfs文件系統,或者遭遇系統崩潰,那麼該文件系統中的所有數據都將丟失
掛在虛擬文件系統命令如下:
mount -t tmpfs source target
?
其中source只有在/proc/mounts中可以看到,沒有其他用途。
例如:

除了用於用戶應用程序以外,tmpfs文件系統還有以下兩個特殊用途:
- 由內核內部掛在的隱形tmpfs文件系統,用於實現System V共享內存和共享匿名內存映射。
- 掛在與/dev/shm的tmpfs文件系統,為glibc用以實現POSIX共享內存和POSIX信號量。
參考資料
《Linux/Unix系統編程手冊(上冊)》 第14章