第十一章學習筆記
讀書筆記
這一章學習了linux當中的檔案系統EXT2。只要我們充分理解了一個檔案系統,那麼就可以輕鬆改編其他任何檔案系統。本章首先描述了EXT2檔案系統在Linux中的歷史地位以及EXT3/EXT4檔案系統的當前狀況;用程式設計示例展示了各種EXT2資料結構以及如何遍歷EXT2檔案系統樹;介紹瞭如何實現支援Linux核心中所有檔案操作的EXT2檔案系統;展示瞭如何通過虛擬磁碟的mount_root 來構建基本檔案系統;將檔案系統的實現劃分為3個級別,級別1擴充套件了基本檔案系統,以實現檔案系統樹,級別2實現了檔案內容的讀/寫操作,級別3實現了檔案系統的掛載/裝載和檔案保護;描述了各個級別檔案系統函式的演算法,並通過程式設計示例演示了它們的實現過程;將所有級別融合到一個程式設計專案中;最後,將所有程式設計示例和練習整合到一個完全有效的檔案系統中。
知識點總結
1、Linux最傳統的磁碟檔案系統(filesystem)使用的是EXT2
2、硬碟組成與分割
磁碟的物理組成,整顆磁碟的組成主要有:
圓形的磁碟盤(主要記錄資料的部分);
機械手臂,與在機械手臂上的磁碟讀取頭(可擦寫磁碟盤上的資料);
主軸馬達,可以轉動磁碟盤,讓機械手臂的讀取頭在磁碟盤上讀寫資料
扇區(Sector)為最小的物理儲存單位,每個扇區為 512 bytes;
將扇區組成一個圓,那就是磁柱(Cylinder),磁柱是分割槽(partition)的最小單位;
第一個扇區最重要,裡面有:(1)主要啟動區(Master boot record, MBR)及分割表(partition table), 其中 MBR 佔有 446 bytes,而 partition table 則佔有 64 bytes。
各種介面的磁碟在Linux中的檔名分別為:
/dev/sd[a-p][1-15]:為SCSI, SATA, U盤, Flash閃盤等介面的磁碟檔名;
/dev/hd[a-d][1-63]:為 IDE 介面的磁碟檔名;
3、data block (資料區塊)
data block 是用來放置檔案內容資料地方,在 Ext2 檔案系統中所支援的 block 大小有 1K, 2K 及 4K 三種而已。在格式化時 block 的大小就固定了,且每個 block 都有編號,以方便 inode 的記錄。 由於 block大小的差異,會導致該檔案系統能夠支援的最大磁碟容量與最大單一檔案容量並不相同。 因為 block 大小而產生的 Ext2 檔案系統限制如下:
Block 大小 1KB 2KB 4KB
最大單一檔案限制 16GB 256GB 2TB
最大檔案系統總容量 2TB 8TB 16TB
原則上,block 的大小與數量在格式化完就不能夠再改變了(除非重新格式化);
每個 block 內最多隻能夠放置一個檔案的資料;
如果檔案大於 block 的大小,則一個檔案會佔用多個 block 數量;
若檔案小於 block ,則該 block 的剩餘容量就不能夠再被使用了(磁碟空間會浪費)。
4、 EXT2檔案系統由以下幾個部分組成:
Boot Sector:上圖啟動塊(Boot Sector),是用來儲存磁碟分割槽資訊和啟動資訊,任何檔案系統給都不能缺少啟動塊。啟動塊大小並不是我們前面所說的4KB,而是1KB,是由PC標準定義的。
Block Group:啟動塊之後才是ext2檔案系統的開始。ext2檔案系統將整個分區劃分為大小相等的塊組(Block Group),每個塊組由以下部分組成:
Super Block:超級塊主要有兩個功能:1)超級塊結構給出了檔案系統的全域性資訊。例如塊大小,檔案系統的版本等等。2)超級塊結構包含一些函式指標,例如super_operation的成員函式read_inode提供了讀取inode資訊的功能。每個具體的檔案系統一般都要提供這個函式來實現對inode資訊的讀取,例如ext2檔案系統提供的具體函式是ext2_read_inode。
GDT(Group Descriptor Table),組描述符表。由很多組描述符組成,整個分割槽分成多少個組就對應有多少個組描述符。每個組描述符(Group Descriptor)儲存一個組的描述資訊,例如在這個組中從哪裡開始是inode表,從哪裡開始是資料塊,空閒的inode和資料塊還有多少個等等。
Block Bitmap,塊點陣圖。塊點陣圖就是用來描述整個塊組中哪些塊已用哪些塊空閒的,它本身佔一個塊,其中的每個bit代表本塊組中的一個塊,這個bit為1表示該塊已用,這個bit為0表示該塊空閒可用。
5、EXT2的索引節點inode
在EXT2檔案系統中每個檔案與目錄由惟一的inode來描述。每個資料塊組的EXT2 inode被儲存在inode表中,同時還有一個位圖被系統用來跟蹤已分配和未分配的inode。
EXT2通過索引節點中的資料塊指標陣列進行邏輯塊到物理塊的對映。在EXT2索引節點中,資料塊中陣列共有15項,前12個為直接指標,後三個分別為“一次間接指標”、“二次間接指標”、“三次間接指標”,EXT2預設的物理塊大小為1KB,塊地址佔4個位元組,所以每個物理塊可以儲存256個地址。這樣,檔案大小最大可達12KB+256KB+64MB+16GB。但實際上,Linux是32位系統,故檔案大小最大隻能為4GB,及整個檔案系統都被一個檔案所佔用。
6、EXT2檔案系統的節點資訊結構
與EXT2超級塊類似,當磁碟上的索引節點調入記憶體後,除了要填寫VFS的索引節點外,系統還要根據它填寫另一個數據結構ext2_inode_info,其作用也是為了儲存特定檔案系統自己的特性。
結構ext2_inode_info分析如下:
7、EXT2檔案系統的組描述符
在塊組中緊跟著超級塊後面的塊是組描述符,在start_sect+block_size*2位置上。乘以2的原因是block_size是KByte為單位,我們用扇區訪問。組描述符表每一項為組描述符,是一個叫ext2_group_desc的資料結構,供32位元組。它用來描述某個塊組的整體資訊。
找到了組描述符,可得到很多資訊,如該組塊組點陣圖的位置,該組塊inode點陣圖位置,該組塊inode表的位置等。
組描述符的定義如下:
最有收穫的內容
通過學習檔案系統,可以從系統層面去理解檔案的儲存,比如要存一個hello的檔案,有以下步驟:
1)核心載入塊組0中的GDT,從GDT中找出inode bitmap,從inode bitmap中找出inode table中空閒的inode。
2)申請一個inode。inode主要包含兩部分內容:檔案屬性(68Bytes),資料塊指標(60Bytes)。資料塊指標指向儲存hello檔案目錄項和檔案內容的Data Block。
3)將檔案內容和檔案的目錄資訊分別存在對應的Data Block中。
4)修改對應的inode Bitmap 和 Block Bitmap。
此外,可以根據給定檔案路徑名,利用OS找到檔案的位置,比如對路徑“/home/hello”,找到檔案位置有以下步驟:
1)查詢根目錄的目錄項。Linux有規定,根目錄的目錄項必須存放在2號inode中。
2)根目錄的目錄項中存著根目錄下的子目錄目錄項和檔案的資料塊資訊。通過根目錄的目錄項可以找到home對應的inode。
3)根據home對應的inode找到home的目錄項。
4)在home目錄項中找到hello檔案的inode。
5)根據hello檔案的inode中的資料塊指標找到儲存有hello檔案內容的資料塊。
問題和解決思路
1、檢視檔案作業系統
無論是Ext2檔案系統還是Ext3檔案系統又或者是Ext4檔案系統,寫入cache memory區塊的這個過程是不會改變的。以上示例效果中還有一個叫做buffers memory的記憶體區塊,這個區塊快取了檔案系統的部分Inode資訊,這樣保證了作業系統不會隨時到檔案系統上尋找Inode——優化檔案系統的讀效能。cache memory區塊和buffers memory區塊由作業系統自行管理,它們只會使用當前沒有被應用程式佔用的空閒記憶體。當應用程式請求新的記憶體區塊且空閒記憶體不夠時,作業系統會釋放部分cache memory區塊或者buffers memory區塊。後文我們講解Linux下的Page Cache技術時,還會對這部分知識進行詳細講解。當cache memory區塊寫滿或者到達一個等待時間後,作業系統就會正式開始向檔案系統寫資料了。
在Ext2檔案系統中,完成檔案寫入的過程可以簡要的進行如下描述:首先檔案系統會在收到檔案寫入請求後根據演算法尋找一個還沒有使用的Inode,這個演算法過程根據不同檔案系統小版本和Linux核心版本的不同而有所變化,但尋找原則都是一樣的,即儘可能為檔案尋找連續的inode和data block。上文已經提到Ext檔案系統中,每一個block group都有Block bitmap區域和Inode bitmap區域分別用於記錄block group中的block和Inode的使用情況。在尋找Inode的這個步驟中,block group的Block bitmap、Inode bitmap區域還不會被寫入任何變化,block group的Group description table區域也不會被寫入任何變化。
Linux支援的檔案作業系統
可以通過命令ls -l /lib/modules/$(uname -r)/kernel/fs
來檢視
2、df、du命令的學習
df(英文全拼:disk free) 命令用於顯示目前在 Linux 系統上的檔案系統磁碟使用情況統計。
列指定檔案系統的名稱,第二列指定一個特定的檔案系統1K-塊1K是1024位元組為單位的總記憶體。用和可用列正在使用中,分別指定的記憶體量。
使用列指定使用的記憶體的百分比,而最後一欄"安裝在"指定的檔案系統的掛載點。
用一個-i選項的df命令的輸出顯示inode資訊而非塊使用量。
-h選項,通過它可以產生可讀的格式df命令的輸出
--total 可以顯示所有的資訊
du命令,檢視目錄和檔案容量
只顯示當前目錄下面的子目錄的目錄大小和當前目錄的總的大小。