1. 程式人生 > 其它 >【作業系統】【讀書筆記】檔案系統實現

【作業系統】【讀書筆記】檔案系統實現

檔案系統實現

概述

  • 檔案系統是純軟體實現

  • 檔案系統的兩個重點:資料結構、訪問方法

    • 如何組織和儲存元資料?陣列、樹等等

    • 如何高效能的訪問檔案?

    • 心智模型:研究檔案系統時,聚焦於核心問題,而不要囿於程式碼的細節

  • 下面討論的都是簡單檔案系統(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,或者使用原始磁碟介面從而完全避免使用檔案系統