當前,除了linux標準的檔案系統Ext2/Ext3/Ext4外,存在很多種檔案系統,比如reiserfs, xfs, Windows的vfat NTFS,網路檔案系統nfs 以及flash 檔案系統jffs2, yaffs/yaffs2 ubifs。linux通過叫做VFS的中介層最這些檔案系統提供了完美的支援。
對於使用者來說,這些檔案系統是幾乎透明的,在大部分情況下,使用者通過libc和kernel的VFS互動,不需要關心底層檔案系統實現,但是有時應用程式也需要考慮底層檔案系統限制(比如fat vfat不支援連結,比如各個檔案系統支援最大檔案限制不同)。
VFS存在的意義
1. 向上對應用程式層提供一個標準的檔案操作介面;
2. 對下向檔案系統提供一個靈活的介面,以便其他動作系統的檔案系統可以方便的移植到Linux上;
3. VFS內部則通過系列高效的管理機制,比如inode cache, dentry cache 以及檔案系統的預讀等技術,使得底層檔案系統不需沉溺到複雜的核心操作,即可獲得高效能;
4. 此外VFS把一些複雜的操作分盡量抽象到VFS內部,使得底層檔案系統實現更簡單。
VFS架構圖
檔案系統分類
檔案系統一般可以分為以下幾類
1. 磁碟檔案系統
這類檔案系統數目最多,最常見:ext2/ext3/ext4檔案系統;resierfs檔案系統 SGI的XFS檔案系統;jffs2 yaffs ubifs等flash檔案系統;crasmfs squashfs等唯讀檔案系統;fat vfa ntfs等windows檔案系統;
這類檔案系統大部分都是基於塊裝置的檔案系統,檔案系統的資料和中繼資料都儲存在塊裝置上;flash檔案系統略有差別,flash檔案系統是位於MTD之上的,
flash檔案系統需要處理壞快,垃圾收集,磨損平衡等複雜的功能。f隨著SD/MMC卡的普及,以及flash檔案系統在可擴充性,啟動速度上的先天不足。flash檔案系統已經慢慢退出了嵌入式舞台。
cramfs squashfs存在的意義在於簡單,高效,穩定(簡單的東西自然穩定),在檔案系統唯讀情境,仍然會被用到。二者的共同特點就是唯讀,壓縮。我們要有這樣一個概念,檔案系統的複雜來源於寫資料,刪除,truncate操作,目錄添加刪除,因此一個唯讀檔案系統遠比可讀寫檔案系統簡單。最直觀的方法就是查看cramfs檔案系統實現代碼,只有區區兩個小檔案。
Reiserfs 提出了很多檔案系統的新概念,對小檔案的讀寫操作做了很大的最佳化,當然新概念過多,也是導致可讀性可理解性差的原因。此外由於reiserfs的作者Hans reiserfs因為殺妻罪名成立,所以reiserfs的開發也受到了影響。
XFS相當的複雜,後面我會單獨開一片分析
2. 特別的檔案系統
此類檔案系統也很常用,他們不是提供常規檔案儲存體和訪問,檔案系統建立在記憶體之上,提供特殊的檔案系統功能。如proc檔案系統,pipe檔案系統,以及tmpfs
3. 網路檔案系統
包括NFS CODA AFS等網路檔案系統
通用檔案模型
VFS為底層檔案系統提供了抽象,有兩種方式提供這種抽象。
1. 提供一個最小的通用模型,使得這個模型支援的功能是所有檔案系統的最小交集
2. 提供一個盡量大的通用模型,使得這個模型包含所有檔案系統功能的合集。
Linux採用第二種策略來實現VFS,因此VFS封裝了底層檔案系統的所有功能和抽象,VFS負責把應用程式層的請求轉寄給特定的檔案系統。
在處理檔案時,應用空間和核心空間使用的對象是不同的。對應用程式來說,檔案描述符用來表示一個檔案,這個檔案描述符是開啟檔案時核心分配給這個檔案的一個整數,注意,這個檔案描述符只在本進程內有效;而對於核心來說,則使用一個inode來表示一個檔案,這個inode可能對應著應用程式層多個進程內的多個檔案描述符。
inode
核心中的每一個檔案或者目錄都有一個inode,inode由兩個主要部分組成:
1. 描述檔案狀態的中繼資料,檔案中繼資料套件括檔案大小,許可權,類型,時間;
2. 檔案資料描述,則用來定義檔案資料在磁碟上的存放位置。
inode僅僅是檔案在核心記憶體中的表現形式,雖然每個檔案都有inode,但是並不是每個檔案在磁碟上都有對應磁碟inode,實際上有些檔案系統並沒有磁碟inode,inode的產生有時要藉助檔案系統掃描。
連結
連結是unix特有的概念,又分為軟連結和永久連結
軟連結又稱為符號連結,軟連結檔案內容指向一個檔案路徑,也就是檔案真實位置,軟連結指向的檔案也可以是軟連結
永久連結是兩個檔案分享權限設定同一個inode,
並不是所有的檔案系統都支援符號連結和永久連結,比如fat, yaffs等檔案系統並不支援符號連結。一般來說,沒有磁碟目錄結構的檔案系統肯定不支援永久連結,而沒有磁碟inode的肯定不支援連結。
軟永久連結雖然為linux/unix操作管理帶來了很多便利,但是在很多軟體實現上,往往引入很大的複雜性。
VFS 物件類型
VFS通用模型包含以下類型對象:
1. super block
隱藏檔系統相關的資訊,對於磁碟檔案系統來說,這個對象通常對應磁碟上的一個檔案系統控制塊(磁碟super block)
2. inode
儲存一個檔案相關的資訊,對於磁碟檔案系統,這個對象通常對應磁碟上的一個檔案控制區(磁碟inode)。每一個inode都對應一個編號,可以在檔案系統內唯一標識這個檔案。
3. file
file是和進程相關的,file代表一個開啟的檔案,file和inode之間是多對一的關係,因為多個進程可以開啟同一個檔案,系統會為每一次開啟都建立一個file結構。
4. dentry
底層檔案系統的許多操作嚴重依賴檔案的inode,在進行檔案操作前,我們需要根據路徑名找到檔案對應的inode。我們知道檔案系統是樹狀結構的,因此需要從根目錄通過分類樹找到要操作的檔案或目錄,這個遍曆過程涉及到磁碟操作,非常耗時。根據局部性原理,很有必要把這個尋找過程cache起來,dentry就是為了加快目錄遍曆操作引入的資料結構。
每一個基於磁碟的檔案系統,都有特定的方法用來構建分類樹。一般來說有兩種方式:
1. 磁碟上儲存著目錄項
2. 通過磁碟檔案的父子關係重建目錄項