4.7 文件系統層次結構
現代操作系統有多種文件系統類型(如FAT32、NTFS、 ext2、ext3、ext4等),因此文件系統的層次結構也不盡相同。圖4-11是一種合理的層次結構。
圖4-11文件系統層次結構
1) 用戶調用接口
文件系統為用戶提供與文件及目錄有關的調用,如新建、打開、讀寫、關閉、刪除文件,建立、刪除目錄等。此層由若干程序模塊組成,每一模塊對應一條系統調用,用戶發出系統調用時,控制即轉入相應的模塊。2) 文件目錄系統
文件目錄系統的主要功能是管理文件目錄,其任務有管理活躍文件目錄表、管理讀寫狀態信息表、管理用戶進程的打開文件表、管理與組織在存儲設備上的文件目錄結構、調用下一級存取控制模塊。3) 存取控制驗證
實現文件保護主要由該級軟件完成,它把用戶的訪問要求與FCB中指示的訪問控制權限進行比較,以確認訪問的合法性。4) 邏輯文件系統與文件信息緩沖區
邏輯文件系統與文件信息緩沖區的主要功能是根據文件的邏輯結構將用戶要讀寫的邏輯記錄轉換成文件邏輯結構內的相應塊號。5) 物理文件系統
物理文件系統的主要功能是把邏輯記錄所在的相對塊號轉換成實際的物理地址。6) 分配模塊
分配模塊的主要功能是管理輔存空間,即負責分配輔存空閑空間和回收輔存空間。7) 設備管理程序模塊
設備管理程序模塊的主要功能是分配設備、分配設備讀寫用緩沖區、磁盤調度、啟動設備、處理設備中斷、釋放設備讀寫緩沖區、釋放設備等。4.8 文件系統的實現:目錄實現和文件實現
目錄實現
在讀文件前,必須先打開文件。打開文件時,操作系統利用路徑名找到相應目錄項,目 錄項中提供了查找文件磁盤塊所需要的信息。目錄實現的基本方法有線性列表和哈希表兩種。1) 線性列表
最簡單的目錄實現方法是使用存儲文件名和數據塊指針的線性表。創建新文件時,必須 首先搜索目錄表以確定沒有同名的文件存在,然后在目錄表后增加一個目錄項。刪除文件則 根據給定的文件名搜索目錄表,接着釋放分配給它的空間。若要重用目錄項,有許多方法: 可以將目錄項標記為不再使用,或者將它加到空閑目錄項表上,還可以將目錄表中最后一個 目錄項復制到空閑位置,並降低目錄表長度。釆用鏈表結構可以減少刪除文件的時間。其優 點在於實現簡單,不過由於線性表的特殊性,比較費時。2) 哈希表
哈希表根據文件名得到一個值,並返回一個指向線性列表中元素的指針。這種方法的優點是查找非常迅速,插入和刪除也較簡單,不過需要一些預備措施來避免沖突。最大的困難是哈希表長度固定以及哈希函數對表長的依賴性。目錄查詢是通過在磁盤上反復搜索完成,需要不斷地進行I/O操作,開銷較大。所以如前面所述,為了減少I/O操作,把當前使用的文件目錄復制到內存,以后要使用該文件時只要在內存中操作,從而降低了磁盤操作次數,提高了系統速度。
文件實現
1. 文件分配方式
文件分配對應於文件的物理結構,是指如何為文件分配磁盤塊。常用的磁盤空間分配方法有三種:連續分配、鏈接分配和索引分配。有的系統(如RD0S操作系統)對三種方法都支持,但是更普遍的是一個系統只提供一種方法的支持。1) 連續分配。
連續分配方法要求每個文件在磁盤上占有一組連續的塊,如圖4-12所示。 磁盤地址定義了磁盤上的一個線性排序。這種排序使作業訪問磁盤時需要的尋道數和尋道時間最小。
圖4-12 連續分配
文件的連續分配可以用第一塊的磁盤地址和連續塊的數量來定義。如果文件有n塊長並從位置b開始,那么該文件將占有塊b, b+1, b+2, …, b+n-1。 一個文件的目錄條目包括 開始塊的地址和該文件所分配區域的長度。
連續分配支持順序訪問和直接訪問。其優點是實現簡單、存取速度快。缺點在於,文件長度不宜動態增加,因為一個文件末尾后的盤塊可能已經分配給其他文件,一旦需要增加,就需要大量移動盤塊。此外,反復增刪文件后會產生外部碎片(與內存管理分配方式中的碎片相似),並且很難確定一個文件需要的空間大小,因而只適用於長度固定的文件。
2) 鏈接分配。
鏈接分配是釆取離散分配的方式,消除了外部碎片,故而顯著地提高了磁盤空間的利用率;又因為是根據文件的當前需求,為它分配必需的盤塊,當文件動態增長時,可以動態地再為它分配盤塊,故而無需事先知道文件的大小。此外,對文件的增、刪、改也非常方便。鏈接分配又可以分為隱式鏈接和顯式鏈接兩種形式。隱式連接如圖4-13所示。每個文件對應一個磁盤塊的鏈表;磁盤塊分布在磁盤的任何 地方,除最后一個盤塊外,每一個盤塊都有指向下一個盤塊的指針,這些指針對用戶是透明的。目錄包括文件第一塊的指針和最后一塊的指針。
創建新文件時,目錄中增加一個新條目。每個目錄項都有一個指向文件首塊的指針。該指針初始化為NULL以表示空文件,大小字段為0。寫文件會通過空閑空間管理系統找到空 閑塊,將該塊鏈接到文件的尾部,以便寫入。讀文件則通過塊到塊的指針順序讀塊。
隱式鏈接分配的缺點在於無法直接訪問盤塊,只能通過指針順序訪問文件,以及盤塊指 針消耗了一定的存儲空間。隱式鏈接分配的穩定性也是一個問題,系統在運行過程中由於軟 件或者硬件錯誤導致鏈表中的指針丟失或損壞,會導致文件數據的丟失。

圖4-13 隱式鏈接分配
顯式鏈接,是指把用於鏈接文件各物理塊的指針,顯式地存放在內存的一張鏈接表中。 該表在整個磁盤僅設置一張,每個表項中存放鏈接指針,即下一個盤塊號。在該表中,凡是 屬於某一文件的第一個盤塊號,或者說是每一條鏈的鏈首指針所對應的盤塊號,均作為文件 地址被填入相應文件的FCB的“物理地址”字段中。由於查找記錄的過程是在內存中進行 的,因而不僅顯著地提高了檢索速度,而且大大減少了訪問磁盤的次數。由於分配給文件的 所有盤塊號都放在該表中,故稱該表為文件分配表(File Allocation Table, FAT)。
3) 索引分配
鏈接分配解決了連續分配的外部碎片和文件大小管理的問題。但是,鏈接分配不能有效支持直接訪問(FAT除外)。索引分配解決了這個問題,它把每個文件的所有的盤塊號都集中放在一起構成索引塊(表),如圖4-14所示。
圖4-14 索引分配
每個文件都有其索引塊,這是一個磁盤塊地址的數組。索引塊的第i個條目指向文件的 第i個塊。目錄條目包括索引塊的地址。要讀第i塊,通過索引塊的第i個條目的指針來查 找和讀入所需的塊。
創建文件時,索引塊的所有指針都設為空。當首次寫入第i塊時,先從空閑空間中取得 一個塊,再將其地址寫到索引塊的第i個條目。索引分配支持直接訪問,且沒有外部碎片問 題。其缺點是由於索引塊的分配,增加了系統存儲空間的開銷。索引塊的大小是一個重要的 問題,每個文件必須有一個索引塊,因此索引塊應盡可能小,但索引塊太小就無法支持大文 件。可以釆用以下機制來處理這個問題。
鏈接方案:一個索引塊通常為一個磁盤塊,因此,它本身能直接讀寫。為了處理大文件, 可以將多個索引塊鏈接起來。
多層索引:多層索引使第一層索引塊指向第二層的索引塊,第二層索引塊再指向文件塊。 這種方法根據最大文件大小的要求,可以繼續到第三層或第四層。例如,4096B的塊,能在 索引塊中存入1024個4B的指針。兩層索引允許1048576個數據塊,即允許最大文件為4GB。
混合索引:將多種索引分配方式相結合的分配方式。例如,系統既釆用直接地址,又采 用單級索引分配方式或兩級索引分配方式。
表4-2是三種分配方式的比較。
| 訪問第n個記錄 | 優 點 | 缺 點 | |
|---|---|---|---|
| 順序分配 | 需訪問磁盤1次 | 順序存取時速度怏,當文件是定長時 可以根據文件起始地址及記錄長度進行 隨機訪問 | 文件存儲要求連續的存儲空間,會產 生碎片,也不利於文件的動態擴充 |
| 鏈接分配 | 需訪問磁盤n次 | 可以解決外存的碎片問題,提髙了外 存空間的利用率,動態增長較方便 | 只能按照文件的指針鏈順序訪問,查 找效率低,指針信息存放消耗外存空間 |
| 索引分配 | m級需訪問磁盤m+1次 | 可以隨機訪問,易於文件的增刪 | 索引表增加存儲空間的開銷,索引表 的查找策略對文件系統效率影響較大 |
此外,訪問文件需要兩次訪問外存——首先要讀取索引塊的內容,然后再訪問具體的磁 盤塊,因而降低了文件的存取速度。為了解決這一問題,通常將文件的索引塊讀入內存的緩 沖區中,以加快文件的訪問速度。
2. 文件存儲空間管理
1) 文件存儲器空間的划分與初始化。
一般來說,一個文件存儲在一個文件卷中。文件卷可以是物理盤的一部分,也可以是整個物理盤,支持超大型文件的文件卷也可以由多個物理盤組成,如圖4-15所示。在一個文件卷中,文件數據信息的空間(文件區)和存放文件控制信息FCB的空間(目錄區)是分離的。由於存在很多種類的文件表示和存放格式,所以現代操作系統中一般都有很多不同的文件管理模塊,通過它們可以訪問不同格式的邏輯卷中的文件。邏輯卷在提供文件服務前,必須由對應的文件程序進行初始化,划分好目錄區和文件區,建立空閑空間管理表格及存放邏輯卷信息的超級塊。
2) 文件存儲器空間管理。
文件存儲設備分成許多大小相同的物理塊,並以塊為單位交換信息,因此,文件存儲設備的管理實質上是對空閑塊的組織和管理,它包括空閑塊的組織、 分配與回收等問題。
圖4-15 邏輯卷與物理盤的關系
①空閑表法
空閑表法屬於連續分配方式,它與內存的動態分配方式類似,為每個文件分配一塊連續的存儲空間。系統為外存上的所有空閑區建立一張空閑盤塊表,每個空閑區對應於一個空閑表項,其中包括表項序號、該空閑區第一個盤塊號、該區的空閑盤塊數等信息。再將所有空閑區按其起始盤塊號遞增的次序排列,見表4-3。
空閑盤區的分配與內存的動態分配類似,同樣是釆用首次適應算法、循環首次適應算法等。例如,在系統 為某新創建的文件分配空閑盤塊時,先順序地檢索空閑 盤塊表的各表項,直至找到第一個其大小能滿足要求的 空閑區,再將該盤區分配給用戶,同時修改空閑盤塊表。 系統在對用戶所釋放的存儲空間進行回收時,也釆取類似於內存回收的方法,即要考慮回收區是否與空閑表中插入點的前區和后區相鄰接,對 相鄰接者應予以合並。
| 序號 | 第一個空閑盤塊號 | 空閑盤塊數 |
|---|---|---|
| 1 | 2 | 4 |
| 2 | 9 | 3 |
| 3 | 15 | 5 |
| 4 | -- | -- |
②空閑鏈表法
將所有空閑盤區拉成一條空閑鏈,根據構成鏈所用的基本元素不同,可把鏈表分成兩種 形式:空閑盤塊鏈和空閑盤區鏈。
空閑盤塊鏈是將磁盤上的所有空閑空間,以盤塊為單位拉成一條鏈。當用戶因創建文件 而請求分配存儲空間時,系統從鏈首開始,依次摘下適當的數目的空閑盤塊分配給用戶。當 用戶因刪除文件而釋放存儲空間時,系統將回收的盤塊依次插入空閑盤塊鏈的末尾。這種方 法的優點是分配和回收一個盤塊的過程非常簡單,但在為一個文件分配盤塊時,可能要重復 多次操作。
空閑盤區鏈是將磁盤上的所有空閑盤區(每個盤區可包含若干個盤塊)拉成一條鏈。在 每個盤區上除含有用於指示下一個空閑盤區的指針外,還應有能指明本盤區大小(盤塊數) 的信息。分配盤區的方法與內存的動態分區分配類似,通常釆用首次適應算法。在回收盤區 時,同樣也要將回收區與相鄰接的空閑盤區相合並。
③位示圖法
位示圖是利用二進制的一位來表示磁盤中一個盤塊的使用情況,磁盤上所有的盤塊都有 一個二進制位與之對應。當其值為“0”時,表示對應的盤塊空閑;當其值為“1”時,表示 對應的盤塊已分配。位示圖法示意如圖4-16所示。
盤塊的分配:
- 順序掃描位示圖,從中找出一個或一組其值為“0”的二進制位。
- 將所找到的一個或一組二進制位,轉換成與之對應的盤塊號。假定找到的其值為“0” 的二進制位,位於位示圖的第i行、第j列,則其相應的盤塊號應按下式計算(n代表每行 的位數):
b = n (i-1) + j - 修改位示圖,令map[i, j] = 1。
盤塊的回收:
- 將回收盤塊的盤塊號轉換成位示圖中的行號和列號。
轉換公式為
i=(b-1)DIVn+l
j=(b-l)MOD n+1 - 修改位示圖,令map[i, j] = 0。
空閑表法和空閑鏈表法都不適合用於大型文件系統,因為這會使空閑表或空閑鏈表太 大。在UNIX系統中釆用的是成組鏈接法,這種方法結合了空閑表和空閑鏈表兩種方法,克 月艮了表太大的缺點。其大致的思想是:把順序的n個空閑扇區地址保存在第一個空閑扇區內, 其后一個空閑扇區內則保存另一順序空閑扇區的地址,如此繼續,直至所有空閑扇區均予以 鏈接。系統只需要保存一個指向第一個空閑扇區的指針。假設磁盤最初全為空閑扇區;其成 組鏈接如圖4-17所示。通過這種方式可以迅速找到大批空閑塊地址。

圖4-17 成組鏈接法示意圖
表示文件存儲器空閑空間的“位向量”表或第一個成組鏈塊以及卷中的目錄區、文件區 划分信息都需要存放在輔存儲器中,一般放在卷頭位置,在UNIX系統中稱為“超級塊”。 在對卷中文件進行操作前,“超級塊”需要預先讀入系統空間的主存,並且經常保持主存“超 級塊”與輔存卷中“超級塊”的一致性。
注意:位示圖法,行和列都是從1開始編號。特別注意, 如果題目中指明從0開始編號,則上述的計算方法要進行相應調整。
