檔案系統的實作
在對檔案有了基本認識之後,現在是時候把目光轉移到檔案系統的
實作
上了。之前使用者關心的一直都是檔案是怎樣命名的、可以進行哪些操作、目錄樹是什麼,如何找到正确的檔案路徑等問題。而設計人員關心的是檔案和目錄是怎樣存儲的、磁盤空間是如何管理的、如何使檔案系統得以流暢運作的問題,下面我們就來一起讨論一下這些問題。
檔案系統布局
檔案系統存儲在
磁盤
中。大部分的磁盤能夠劃分出一到多個分區,叫做
磁盤分區(disk partitioning)
或者是
磁盤分片(disk slicing)
。每個分區都有獨立的檔案系統,每塊分區的檔案系統可以不同。磁盤的 0 号分區稱為
主引導記錄(Master Boot Record, MBR)
,用來
引導(boot)
計算機。在 MBR 的結尾是
分區表(partition table)
。每個分區表給出每個分區由開始到結束的位址。系統管理者使用一個稱為分區編輯器的程式來建立,調整大小,删除和操作分區。這種方式的一個缺點是很難适當調整分區的大小,導緻一個分區具有很多可用空間,而另一個分區幾乎完全被配置設定。
MBR 可以用在 DOS 、Microsoft Windows 和 Linux 作業系統中。從 2010 年代中期開始,大多數新計算機都改用 GUID 分區表(GPT)分區方案。
下面是一個用
GParted
進行分區的磁盤,表中的分區都被認為是
活動的(active)
。

當計算機開始引 boot 時,BIOS 讀入并執行 MBR。
引導塊
MBR 做的第一件事就是
确定活動分區
,讀入它的第一個塊,稱為
引導塊(boot block)
并執行。引導塊中的程式将加載分區中的作業系統。為了一緻性,每個分區都會從引導塊開始,即使引導塊不包含作業系統。引導塊占據檔案系統的前 4096 個位元組,從磁盤上的位元組偏移量 0 開始。引導塊可用于啟動作業系統。
在計算機中,引導就是啟動計算機的過程,它可以通過硬體(例如按下電源按鈕)或者軟體指令的方式來啟動。開機後,電腦的 CPU 還不能執行指令,因為此時沒有軟體在主存中,是以一些軟體必須先被加載到記憶體中,然後才能讓 CPU 開始執行。也就是計算機開機後,首先會進行軟體的裝載過程。
重新開機電腦的過程稱為
,從休眠或睡眠狀态傳回計算機的過程不涉及啟動。
重新開機(rebooting)
除了從引導塊開始之外,磁盤分區的布局是随着檔案系統的不同而變化的。通常檔案系統會包含一些屬性,如下
超級塊
緊跟在引導塊後面的是
超級塊(Superblock)
,超級塊 的大小為 4096 位元組,從磁盤上的位元組偏移 4096 開始。超級塊包含檔案系統的所有關鍵參數
- 檔案系統的大小
- 檔案系統中的資料塊數
- 訓示檔案系統狀态的标志
- 配置設定組大小
在計算機啟動或者檔案系統首次使用時,超級塊會被讀入記憶體。
空閑空間塊
接着是檔案系統中
空閑塊
的資訊,例如,可以用位圖或者指針清單的形式給出。
BitMap 位圖或者 Bit vector 位向量
位圖或位向量是一系列位或位的集合,其中每個位對應一個磁盤塊,該位可以采用兩個值:0和1,0表示已配置設定該塊,而1表示一個空閑塊。下圖中的磁盤上給定的磁盤塊執行個體(配置設定了綠色塊)可以用16位的位圖表示為:0000111000000110。
使用連結清單進行管理
在這種方法中,空閑磁盤塊連結在一起,即一個空閑塊包含指向下一個空閑塊的指針。第一個磁盤塊的塊号存儲在磁盤上的單獨位置,也緩存在記憶體中。
碎片
這裡不得不提一個叫做
碎片(fragment)
的概念,也稱為片段。一般零散的單個資料通常稱為片段。 磁盤塊可以進一步分為固定大小的配置設定單元,片段隻是在驅動器上彼此不相鄰的檔案片段。如果你不了解這個概念就給你舉個例子。比如你用 Windows 電腦建立了一個檔案,你會發現這個檔案可以存儲在任何地方,比如存在桌面上,存在磁盤中的檔案夾中或者其他地方。你可以打開檔案,編輯檔案,删除檔案等等。你可能以為這些都在一個地方發生,但是實際上并不是,你的硬碟驅動器可能會将檔案中的一部分存儲在一個區域内,另一部分存儲在另外一個區域,在你打開檔案時,硬碟驅動器會迅速的将檔案的所有部分彙總在一起,以便其他計算機系統可以使用它。
inode
然後在後面是一個
inode(index node)
,也稱作索引節點。它是一個數組的結構,每個檔案有一個 inode,inode 非常重要,它說明了檔案的方方面面。每個索引節點都存儲對象資料的屬性和磁盤塊位置
有一種簡單的方法可以找到它們
ls -lai
指令。讓我們看一下根檔案系統:
inode 節點主要包括了以下資訊
- 模式/權限(保護)
- 所有者 ID
- 組 ID
- 檔案大小
- 檔案的硬連結數
- 上次通路時間
- 最後修改時間
- inode 上次修改時間
檔案分為兩部分,索引節點和塊。一旦建立後,每種類型的塊數是固定的。你不能增加分區上 inode 的數量,也不能增加磁盤塊的數量。
緊跟在 inode 後面的是根目錄,它存放的是檔案系統目錄樹的根部。最後,磁盤的其他部分存放了其他所有的目錄和檔案。
檔案的實作
最重要的問題是記錄各個檔案分别用到了哪些磁盤塊。不同的系統采用了不同的方法。下面我們會探讨一下這些方式。配置設定背後的主要思想是
有效利用檔案空間
和
快速通路檔案
,主要有三種配置設定方案
- 連續配置設定
- 連結清單配置設定
- 索引配置設定
最簡單的配置設定方案是把每個檔案作為一連串連續資料塊存儲在磁盤上。是以,在具有 1KB 塊的磁盤上,将為 50 KB 檔案配置設定 50 個連續塊。
上面展示了 40 個連續的記憶體塊。從最左側的 0 塊開始。初始狀态下,還沒有裝載檔案,是以磁盤是空的。接着,從磁盤開始處(塊 0 )處開始寫入占用 4 塊長度的記憶體 A 。然後是一個占用 6 塊長度的記憶體 B,會直接在 A 的末尾開始寫。
注意每個檔案都會在新的檔案塊開始寫,是以如果檔案 A 隻占用了
3 又 1/2
個塊,那麼最後一個塊的部分記憶體會被浪費。在上面這幅圖中,總共展示了 7 個檔案,每個檔案都會從上個檔案的末尾塊開始寫新的檔案塊。
連續的磁盤空間配置設定有兩個優點。
- 第一,連續檔案存儲實作起來比較簡單,隻需要記住兩個數字就可以:一個是第一個塊的檔案位址和檔案的塊數量。給定第一個塊的編号,可以通過簡單的加法找到任何其他塊的編号。
- 第二點是讀取性能比較強,可以通過一次操作從檔案中讀取整個檔案。隻需要一次尋找第一個塊。後面就不再需要尋道時間和旋轉延遲,是以資料會以全帶寬進入磁盤。
是以,連續的空間配置設定具有
實作簡單
、
高性能
的特點。
不幸的是,連續空間配置設定也有很明顯的不足。随着時間的推移,磁盤會變得很零碎。下圖解釋了這種現象
這裡有兩個檔案 D 和 F 被删除了。當删除一個檔案時,此檔案所占用的塊也随之釋放,就會在磁盤空間中留下一些空閑塊。磁盤并不會在這個位置擠壓掉空閑塊,因為這會複制空閑塊之後的所有檔案,可能會有上百萬的塊,這個量級就太大了。
剛開始的時候,這個碎片不是問題,因為每個新檔案都會在之前檔案的結尾處進行寫入。然而,磁盤最終會被填滿,是以要麼壓縮磁盤、要麼重新使用空閑塊的空間。壓縮磁盤的開銷太大,是以不可行;後者會維護一個空閑清單,這個是可行的。但是這種情況又存在一個問題,為空閑塊比對合适大小的檔案,需要知道該檔案的
最終大小
想象一下這種設計的結果會是怎樣的。使用者啟動 word 程序建立文檔。應用程式首先會詢問最終建立的文檔會有多大。這個問題必須回答,否則應用程式就不會繼續執行。如果空閑塊的大小要比檔案的大小小,程式就會終止。因為所使用的磁盤空間已經滿了。那麼現實生活中,有沒有使用連續配置設定記憶體的媒體出現呢?
CD-ROM
就廣泛的使用了連續配置設定方式。
CD-ROM(Compact Disc Read-Only Memory)
即隻讀CD光牒,也稱作隻讀存儲器。是一種在電腦上使用的光碟。這種光碟隻能寫入資料一次,資訊将永久儲存在光碟上,使用時通過光碟驅動器讀出資訊。
然而 DVD 的情況會更加複雜一些。原則上,一個
90分鐘
的電影能夠被編碼成一個獨立的、大約 4.5 GB 的檔案。但是檔案系統所使用的
UDF(Universal Disk Format)
格式,使用一個 30 位的數來代表檔案長度,進而把檔案大小限制在 1 GB。是以,DVD 電影一般存儲在 3、4個連續的 1 GB 空間内。這些構成單個電影中的檔案塊稱為
擴充區(extends)
就像我們反複提到的,曆史總是驚人的相似,許多年前,連續配置設定由于其
簡單
高性能
被實際使用在磁盤檔案系統中。後來由于使用者不希望在建立檔案時指定檔案的大小,于是放棄了這種想法。但是随着 CD-ROM 、DVD、藍光CD光牒等光學媒體的出現,連續配置設定又流行起來。進而得出結論,
技術永遠沒有過時性
,現在看似很老的技術,在未來某個階段可能又會流行起來。
第二種存儲檔案的方式是為每個檔案構造磁盤塊連結清單,每個檔案都是磁盤塊的連結清單,就像下面所示
每個塊的第一個字作為指向下一塊的指針,塊的其他部分存放資料。如果上面這張圖你看的不是很清楚的話,可以看看整個的連結清單配置設定方案
與連續配置設定方案不同,這一方法可以充分利用每個磁盤塊。除了最後一個磁盤塊外,不會因為磁盤碎片而浪費存儲空間。同樣,在目錄項中,隻要存儲了第一個檔案塊,那麼其他檔案塊也能夠被找到。
另一方面,在連結清單的配置設定方案中,盡管順序讀取非常友善,但是随機通路卻很困難(這也是數組和連結清單資料結構的一大差別)。
還有一個問題是,由于指針會占用一些位元組,每個磁盤塊實際存儲資料的位元組數并不再是 2 的整數次幂。雖然這個問題并不會很嚴重,但是這種方式降低了程式運作效率。許多程式都是以長度為 2 的整數次幂來讀寫磁盤,由于每個塊的前幾個位元組被指針所使用,是以要讀出一個完成的塊大小資訊,就需要目前塊的資訊和下一塊的資訊拼湊而成,是以就引發了查找和拼接的開銷。
使用記憶體表進行連結清單配置設定
由于連續配置設定和連結清單配置設定都有其不可忽視的缺點。是以提出了使用記憶體中的表來解決配置設定問題。取出每個磁盤塊的指針字,把它們放在記憶體的一個表中,就可以解決上述連結清單的兩個不足之處。下面是一個例子
上圖表示了連結清單形成的磁盤塊的内容。這兩個圖中都有兩個檔案,檔案 A 依次使用了磁盤塊位址 4、7、 2、 10、 12,檔案 B 使用了6、3、11 和 14。也就是說,檔案 A 從位址 4 處開始,順着連結清單走就能找到檔案 A 的全部磁盤塊。同樣,從第 6 塊開始,順着鍊走到最後,也能夠找到檔案 B 的全部磁盤塊。你會發現,這兩個連結清單都以不屬于有效磁盤編号的特殊标記(-1)結束。記憶體中的這種表格稱為
檔案配置設定表(File Application Table,FAT)
使用這種組織方式,整個塊都可以存放資料。進而,随機通路也容易很多。雖然仍要順着鍊在記憶體中查找給定的偏移量,但是整個鍊都存放在記憶體中,是以不需要任何磁盤引用。與前面的方法相同,不管檔案有多大,在目錄項中隻需記錄一個整數(起始塊号),按照它就可以找到檔案的全部塊。
這種方式存在缺點,那就是必須要把整個連結清單放在記憶體中。對于 1TB 的磁盤和 1KB 的大小的塊,那麼這張表需要有 10 億項。。。每一項對應于這 10 億個磁盤塊中的一塊。每項至少 3 個位元組,為了提高查找速度,有時需要 4 個位元組。根據系統對空間或時間的優化方案,這張表要占用 3GB 或 2.4GB 的記憶體。FAT 的管理方式不能較好地擴充并應用于大型磁盤中。而這正是最初 MS-DOS 檔案比較實用,并仍被各個 Windows 版本所安全支援。
最後一個記錄各個檔案分别包含哪些磁盤塊的方法是給每個檔案賦予一個稱為
inode(索引節點)
的資料結構,每個檔案都與一個
inode
進行關聯,inode 由整數進行辨別。
下面是一個簡單例子的描述。
給出 inode 的長度,就能夠找到檔案中的所有塊。
相對于在記憶體中使用表的方式而言,這種機制具有很大的優勢。即隻有在檔案打開時,其 inode 才會在記憶體中。如果每個 inode 需要 n 個位元組,最多 k 個檔案同時打開,那麼 inode 占有總共打開的檔案是 kn 位元組。僅需預留這麼多空間。
這個數組要比我們上面描述的
FAT(檔案配置設定表)
占用的空間小的多。原因是用于儲存所有磁盤塊的連結清單的表的大小與磁盤本身成正比。如果磁盤有 n 個塊,那麼這個表也需要 n 項。随着磁盤空間的變大,那麼該表也随之
線性增長
。相反,inode 需要節點中的數組,其大小和可能需要打開的最大檔案個數成正比。它與磁盤是 100GB、4000GB 還是 10000GB 無關。
inode 的一個問題是如果每個節點都會有固定大小的磁盤位址,那麼檔案增長到所能允許的最大容量外會發生什麼?一個解決方案是最後一個磁盤位址不指向資料塊,而是指向一個包含額外磁盤塊位址的位址,如上圖所示。一個更進階的解決方案是:有兩個或者更多包含磁盤位址的塊,或者指向其他存放位址的磁盤塊的磁盤塊。Windows 的 NTFS 檔案系統采用了相似的方法,所不同的僅僅是大的 inode 也可以表示小的檔案。
NTFS 的全稱是,是微軟公司開發的專用系統檔案,NTFS 取代 FAT(檔案配置設定表) 和
New Technology File System
,并在此基礎上進一步改進。例如增強對中繼資料的支援,使用更進階的資料結構以提升性能、可靠性和磁盤空間使用率等。
HPFS(高性能檔案系統)
目錄的實作
檔案隻有打開後才能夠被讀取。在檔案打開後,作業系統會使用使用者提供的路徑名來定位磁盤中的目錄。目錄項提供了查找檔案磁盤塊所需要的資訊。根據系統的不同,提供的資訊也不同,可能提供的資訊是整個檔案的磁盤位址,或者是第一個塊的數量(兩個連結清單方案)或 inode的數量。不過不管用那種情況,目錄系統的主要功能就是 将檔案的 ASCII 碼的名稱映射到定位資料所需的資訊上。
與此關系密切的問題是屬性應該存放在哪裡。每個檔案系統包含不同的檔案屬性,例如檔案的所有者和建立時間,需要存儲的位置。一種顯而易見的方法是直接把檔案屬性存放在目錄中。有一些系統恰好是這麼做的,如下。
在這種簡單的設計中,目錄有一個固定大小的目錄項清單,每個檔案對應一項,其中包含一個固定長度的檔案名,檔案屬性的結構體以及用以說明磁盤塊位置的一個或多個磁盤位址。
對于采用 inode 的系統,會把 inode 存儲在屬性中而不是目錄項中。在這種情況下,目錄項會更短:僅僅隻有檔案名稱和 inode 數量。這種方式如下所示
到目前為止,我們已經假設檔案具有較短的、固定長度的名字。在 MS-DOS 中,具有 1 - 8 個字元的基本名稱和 1 - 3 個字元的可拓展名稱。在 UNIX 版本 7 中,檔案有 1 - 14 個字元,包括任何拓展。然而,幾乎所有的現代作業系統都支援可變長度的擴充名。這是如何實作的呢?
最簡單的方式是給予檔案名一個長度限制,比如 255 個字元,然後使用上圖中的設計,并為每個檔案名保留 255 個字元空間。這種處理很簡單,但是浪費了大量的目錄空間,因為隻有很少的檔案會有那麼長的檔案名稱。是以,需要一種其他的結構來處理。
一種可選擇的方式是放棄所有目錄項大小相同的想法。在這種方法中,每個目錄項都包含一個固定部分,這個固定部分通常以目錄項的長度開始,後面是固定格式的資料,通常包括所有者、建立時間、保護資訊和其他屬性。這個固定長度的頭的後面是一個任意長度的實際檔案名,如下圖所示
上圖是 SPARC 機器使用正序放置。
處理機中的一串字元存放的順序有
正序(big-endian)
之分。正序存放的就是高位元組在前低位元組在後,而逆序存放的就是低位元組在前高位元組在後。
逆序(little-endian)
這個例子中,有三個檔案,分别是
project-budget
personnel
foo
。每個檔案名以一個特殊字元(通常是 0 )結束,用矩形中的叉進行表示。為了使每個目錄項從字的邊界開始,每個檔案名被填充成整數個字,如下圖所示
這個方法的缺點是當檔案被移除後,就會留下一塊固定長度的空間,而新添加進來的檔案大小不一定和空閑空間大小一緻。
這個問題與我們上面探讨的連續磁盤檔案的問題是一樣的,由于整個目錄在記憶體中,是以隻有對目錄進行
緊湊拼接
操作才可節省空間。另一個問題是,一個目錄項可能會分布在多個頁上,在讀取檔案名時可能發生缺頁中斷。
處理可變長度檔案名字的另外一種方法是,使目錄項自身具有固定長度,而将檔案名放在目錄末尾的堆棧中。如上圖所示的這種方式。這種方法的優點是當目錄項被移除後,下一個檔案将能夠正常比對移除檔案的空間。當然,必須要對
堆
進行管理,因為在處理檔案名的時候也會發生缺頁異常。
到目前為止的所有設計中,在需要查找檔案名時,所有的方案都是線性的從頭到尾對目錄進行搜尋。對于特别長的目錄,線性搜尋的效率很低。提高檔案檢索效率的一種方式是在每個目錄上使用
哈希表(hash table)
,也叫做散清單。我們假設表的大小為 n,在輸入檔案名時,檔案名被散列在 0 和 n - 1 之間,例如,它被 n 除,并取餘數。或者對構成檔案名字的字求和或類似某種方法。
無論采用哪種方式,在添加一個檔案時都要對與散列值相對應的散清單進行檢查。如果沒有使用過,就會将一個指向目錄項的指針指向這裡。檔案目錄項緊跟着哈希表後面。如果已經使用過,就會構造一個連結清單(這種構造方式是不是和 HashMap 使用的資料結構一樣?),連結清單的表頭指針存放在表項中,并通過哈希值将所有的表項相連。
查找檔案的過程和添加類似,首先對檔案名進行哈希處理,在哈希表中查找是否有這個哈希值,如果有的話,就檢查這條鍊上所有的哈希項,檢視檔案名是否存在。如果哈希不在鍊上,那麼檔案就不在目錄中。
使用哈希表的優勢是
查找非常迅速
,缺點是
管理起來非常複雜
。隻有在系統中會有成千上萬個目錄項存在時,才會考慮使用散清單作為解決方案。
另外一種在大量目錄中加快查找指令目錄的方法是使用
緩存
,緩存查找的結果。在開始查找之前,會首先檢查檔案名是否在緩存中。如果在緩存中,那麼檔案就能立刻定位。當然,隻有在較少的檔案下進行多次查找,緩存才會發揮最大功效。
共享檔案
當多個使用者在同一個項目中工作時,他們通常需要共享檔案。如果這個共享檔案同時出現在多個使用者目錄下,那麼他們協同工作起來就很友善。下面的這張圖我們在上面提到過,但是有一個更改的地方,就是 C 的一個檔案也出現在了 B 的目錄下。
如果按照如上圖的這種組織方式而言,那麼 B 的目錄與該共享檔案的聯系稱為
連結(link)
。那麼檔案系統現在就是一個
有向無環圖(Directed Acyclic Graph, 簡稱 DAG)
,而不是一棵樹了。
在圖論中,如果一個有向圖從任意頂點出發無法經過若幹條邊回到該點,則這個圖是一個 有向無環圖
,我們不會在此着重探讨關于圖論的東西,大家可以自行 google。
将檔案系統組織成為有向無環圖會使得維護複雜化,但也是必須要付出的代價。
共享檔案
很友善,但這也會帶來一些問題。如果目錄中包含磁盤位址,則當連結檔案時,必須把 C 目錄中的磁盤位址複制到 B 目錄中。如果 B 或者 C 随後又向檔案中添加内容,則僅在執行追加的使用者的目錄中顯示新寫入的資料塊。這種變更将會對其他使用者不可見,進而破壞了共享的目的。
有兩種方案可以解決這種問題。
- 第一種解決方案,磁盤塊不列入目錄中,而是會把磁盤塊放在與檔案本身相關聯的小型資料結構中。目錄将指向這個小型資料結構。這是
中使用的方式(小型資料結構就是 inode)。UNIX
- 在第二種解決方案中,通過讓系統建立一個類型為
的新檔案,并把該檔案放在 B 的目錄下,使得 B 與 C 建立連結。新的檔案中隻包含了它所連結的檔案的路徑名。當 B 想要讀取檔案時,作業系統會檢查 B 的目錄下存在一個類型為 LINK 的檔案,進而找到該連結的檔案和路徑名,然後再去讀檔案,這種方式稱為LINK
符号連結(symbolic linking)
上面的每一種方法都有各自的缺點,在第一種方式中,B 連結到共享檔案時,inode 記錄檔案的所有者為 C。建立一個連結并不改變所有關系,如下圖所示。
第一開始的情況如圖 a 所示,此時 C 的目錄的所有者是 C ,當目錄 B 連結到共享檔案時,并不會改變 C 的所有者關系,隻是把計數 + 1,是以此時 系統知道目前有多少個目錄指向這個檔案。然後 C 嘗試删除這個檔案,這個時候有個問題,如果 C 把檔案移除并清除了 inode 的話,那麼 B 會有一個目錄項指向無效的節點。如果 inode 以後配置設定給另一個檔案,則 B 的連結指向一個錯誤的檔案。系統通過 inode 可知檔案仍在被引用,但是沒有辦法找到該檔案的全部目錄項以删除它們。指向目錄的指針不能存儲在 inode 中,原因是有可能有無數個這樣的目錄。
是以我們能做的就是删除 C 的目錄項,但是将 inode 保留下來,并将計數設定為 1 ,如上圖 c 所示。c 表示的是隻有 B 有指向該檔案的目錄項,而該檔案的前者是 C 。如果系統進行記賬操作的話,那麼 C 将繼續為該檔案付賬直到 B 決定删除它,如果是這樣的話,隻有到計數變為 0 的時刻,才會删除該檔案。
對于
符号連結
,以上問題不會發生,隻有真正的檔案所有者才有一個指向 inode 的指針。連結到該檔案上的使用者隻有路徑名,沒有指向 inode 的指針。當檔案所有者删除檔案時,該檔案被銷毀。以後若試圖通過符号連結通路該檔案将會失敗,因為系統不能找到該檔案。删除符号連結不會影響該檔案。
符号連結的問題是需要額外的開銷。必須讀取包含路徑的檔案,然後要一個部分接一個部分地掃描路徑,直到找到 inode 。這些操作也許需要很多次額外的磁盤通路。此外,每個符号連結都需要額外的 inode ,以及額外的一個磁盤塊用于存儲路徑,雖然如果路徑名很短,作為一種優化,系統可以将它存儲在 inode 中。符号連結有一個優勢,即隻要簡單地提供一個機器的網絡位址以及檔案在該機器上駐留的路徑,就可以連接配接全球任何地方機器上的檔案。
還有另一個由連結帶來的問題,在符号連結和其他方式中都存在。如果允許連結,檔案有兩個或多個路徑。查找一指定目錄及其子目錄下的全部檔案的程式将多次定位到被連結的檔案。例如,一個将某一目錄及其子目錄下的檔案轉存到錄音帶上的程式有可能多次複制一個被連結的檔案。進而,如果接着把錄音帶讀入另一台機器,除非轉出程式具有智能,否則被連結的檔案将被兩次複制到磁盤上,而不是隻是被連結起來。
相關參考:
https://zhuanlan.zhihu.com/p/41358013
https://www.linuxtoday.com/blog/what-is-an-inode.html
https://www.lifewire.com/what-is-fragmentation-defragmentation-2625884
https://www.geeksforgeeks.org/free-space-management-in-operating-system/
https://sites.ualberta.ca/dept/chemeng/AIX-43/share/man/info/C/a_doc_lib/aixprggd/genprogc/fsyslayout.htm
https://en.wikipedia.org/wiki/Disk_partitioning
https://en.wikipedia.org/wiki/Master_boot_record
https://en.wikipedia.org/wiki/Booting
https://www.computerhope.com/jargon/f/fileprot.htm
https://en.wikipedia.org/wiki/File_attribute
https://en.wikipedia.org/wiki/Make_(software)
https://unix.stackexchange.com/questions/60034/what-are-character-special-and-block-special-files-in-a-unix-system
https://www.computerhope.com/jargon/d/director.htm
https://www.computerhope.com/jargon/r/regular-file.htm