【作業系統】【讀書筆記】檔案系統實現
概述
-
檔案系統是純軟體實現
-
檔案系統的兩個重點:資料結構、訪問方法
-
如何組織和儲存元資料?陣列、樹等等
-
如何高效能的訪問檔案?
-
心智模型:研究檔案系統時,聚焦於核心問題,而不要囿於程式碼的細節
-
-
下面討論的都是簡單檔案系統(VSFS)
整體組織
-
資料區:最重要的部分,真實儲存資料的區域
-
塊大小:只用一種塊大小,通常4KB
-
-
inode:檔案系統必須記錄每個檔案的資訊,包括:資料塊、檔案的大小、所有者和訪問許可權、訪問和修改時間等等。因此必須有一塊區域存放這些元資料
-
VSFS使用陣列存放
-
-
記錄資料塊和inode是否空閒:使用data bitmap和inode bitmap
-
記錄磁碟總體資訊:使用Superblock塊,記錄:檔案系統中的剩餘inode、資料塊數目,inode表的起始地址,幻數(標誌檔案系統型別)等等
-
長這樣:
檔案組織:inode
-
檔案的低階名稱:簡單檔案系統中inode存在陣列中,則一個inumber(類似陣列下標,但是經過平移)對應一個inode,inumber即低階名稱(因為inumber和檔案一一對應)
-
可以根據inumber計算出inode的地址
-
-
inode的內容
-
檔案型別(例如,常規檔案、目錄等)
-
大小
-
分配給它的塊數
-
保護資訊(如誰擁有該檔案以及誰可以訪問它)
-
一些時間資訊(包括檔案建立、修改或上次訪問的時間)
-
有關其資料塊駐留在磁碟上的位置的資訊(如某種型別的指標)
-
ext2的inode:存的東西還是很多的
-
如何儲存大檔案
-
多級索引:inode中有一部分索引是直接指標,指向資料區的某些塊;還有間接指標,指向包含更多指標的塊,每個指標指向資料
-
雙重間接指標:多套一層,可以支援更大的檔案範圍!
-
實現:不平衡樹
-
原理:大多數檔案很小
-
-
基於範圍的方法:不需要指向每個塊的指標,而是記錄起始地址 + 長度
-
不夠靈活,但是更緊湊,適用大檔案
-
-
基於連結的方法:inode只存一個指標,然後每個資料塊的末尾連結下一個資料塊
-
缺點:類似連結串列,訪問尾部、隨機訪問等等操作難以進行
-
改進:不把指標資訊存在資料塊的末尾,而是存在記憶體的快取記憶體中
-
-
目錄組織
-
目錄也是一種檔案!因此完全不影響檔案系統的組織,只不過儲存的內容稍有不同:
-
VSFS:基本只包含一個二元組(檔名,inode號)。可能還包含一些別的引數,如檔名的長度等等,如下:
-
刪除檔案:會留下一個空白的條目,因此會有一些方法來標記它(如將inode設為0表示空閒)
-
目錄資料的結構:不一定非要是陣列,也可以是樹或其他的
-
XFS:B樹,檔案建立操作更快(因為需要搜尋目錄,確保檔名沒有衝突)
-
-
空閒空間管理
-
點陣圖(最棒!)
-
空閒列表:早期檔案系統使用的方法,即連結串列。超級塊中儲存第一個空閒塊的指標,然後每個空閒塊都連結下面的空閒塊
-
預分配策略:建立檔案的同時分配一小部分資料塊(因為建立檔案的下一步大概率就是寫),保證部分連續,提高效能
訪問路徑:讀取和寫入
-
所有的遍歷都從根開始,因此係統需要知道根的inode號,一般為2
-
0:保留作為空閒inode的標識
-
1:跟蹤所有的壞塊(特殊用途)
-
-
open函式遍歷的過程:讀目錄檔案的inode -> 讀目錄檔案的data -> 讀下層目錄的inode -> …. -> 找到最終要讀的檔案的inode號
-
下一步,取inode資訊,對使用者許可權進行檢查。如果沒有問題,修改程序的開啟檔案表,分配檔案描述符
-
read讀取內容後會修改檔案的偏移量(在檔案描述符中)
-
例子:
-
缺點:io次數與路徑長度成正比;對於大型目錄,可能需要讀取很多資料塊才能定位到需要的條目
-
優化:B樹!
-
-
-
write寫入磁碟的過程:一般都需要分配新資料塊,故需要多次io
-
讀、寫data的bitmap
-
讀、寫inode的bitmap(修改資料塊的指標)
-
真正寫入資料塊本身
-
如何降低io的成本?引入快取記憶體!
-
快取和緩衝
-
緩衝資源劃分方法
-
靜態劃分:給定固定大小的記憶體用作快取
-
優點:確保有一定的資源可用,提供可預測的效能,實現簡單
-
缺點:可能導致浪費
-
-
動態劃分:虛擬記憶體頁面和檔案系統頁面整合到統一頁面快取中,按需分配
-
缺點:實現可能比較複雜,可能導致空閒資源被佔用,需要使用時花費較長時間回收
-
-
-
為什麼要快取
-
讀操作可以得到極大的優化
-
第一次讀檔案時可能需要很多io,但隨後如果讀取同一目錄下的檔案,則搜尋路徑的過程大部分命中快取,不需要io
-
-
寫入流量不會減少(因為資料確實都要寫入磁碟),但是可以將多個io積累為一批寫入,同時部分寫操作可能會因為拖延而完全避免
-
缺點:考慮系統崩潰導致快取沒有寫入的問題
-
-
-
特殊情況:某些應用程式(如資料庫)不希望寫緩衝,可以通過呼叫fsync()繞過快取直接io,或者使用原始磁碟介面從而完全避免使用檔案系統