- 文件系統是以合理有效的層次結構組織的文件和目錄的集合
- 在Linux中一切皆是文件,其中包含普通文件、目錄、字符設備、塊設備、 套接字等都是文件
- 類型不同的文件都是通過相同的API對其進行操作
文件系統 | 適用場景 | 原因 |
---|---|---|
ext2 | U盤 | ext2不寫日誌,對安全性要求不高,兼容FAT |
ext3 | 對穩定性要求高的地方 | ext4穩定性不高 |
ext4 | 小文件較少 | 不支持inode動態分配 |
xfs | 小文件多 | 支持inode動態分配 |
btrfs | 沒有頻繁的寫操作 | 功能衆多 |
- 通過統一的文件 I/O 系統調用API即可對系統中的任意文件進行操作而無需考慮其所在的具體文件系統格式
- 文件操作可以跨文件系統執行
- Linux文件系統與Windows文件系統區別
Unix/Linux文件系統 | Windows文件系統 |
---|---|
根目錄文件系統 | 多根目錄文件系統 |
文件名區分大小寫 | 文件名不區分大小寫 |
目錄路徑使用正斜槓,如/home/name | 目錄路徑使用反斜線,如C:\Users\zxy |
沒有驅動器號,一切文件都在root目錄下 | 驅動器號標記分區和設備 |
無獨佔訪問權限 | 獨佔訪問權限 |
- 根據上圖可以看到,我們經常操作的文件函數底層調用底層內核函數,通過vfs虛擬文件系統來管理底層的不同的文件系統,所以我們不需要了解所操作的文件的文件系統爲何。
- 虛擬文件系統是Linux 內核中的一個軟件層,對內實現文件系統的抽象,允許不同的文件系統共存,對外向應用程序提供統一的文件系統接口。
- 爲了能夠支持不同文件系統,VFS 定義了所有文件系統都支持的基本的、抽象的接口和數據結構。
- 實際文件系統實現VFS 定義的抽象接口和數據結構,將自身的諸如文件、目錄等概念在形式上與VFS的定義保持一致,在統一的接口和數據結構下隱藏了具體的實現細節。
VFS
VFS中的數據結構
- 超級塊(super block):用於存儲文件系統的控制信息的數據結構。描述文件系統的狀態、文件系統類型、大小、區塊數、索引節點數等,存放於磁盤的特定扇區中。
- 索引節點(inode):用於存儲文件的元數據(文件的基本信息)的一個數據結構,包含諸如文件的大小、擁有者、創建時間、磁盤位置等信息。
- 目錄項(dentry):目錄被用來容納文件,目錄可以包含子目錄,層層嵌套以形成 文件路徑。
- 文件對象(file):一組在邏輯上具有完整意義的信息項的系列。
VFS-超級塊(super block)
- 超級塊用來描述整個文件系統的信息。每個具體的文件系統都有各自的超級塊
- VFS超級塊是各種具體文件系統在安裝時建立的,並在卸載時被自動刪除,其數據結構是 super_block
- 所有超級塊對象以雙向環形鏈表的形式鏈接在一起
struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t 具體文件系統的塊設備標識符*/
unsigned long s_blocksize; //以字節爲單位數據塊的大小
unsigned char s_blocksize_bits; //塊大小的值佔用的位數
unsigned char s_dirt;
unsigned long long s_maxbytes; /* Max file size */
struct file_system_type *s_type; //指向文件系統的file_system_tyep數據結構的指針
const struct super_operations *s_op;//指向具體文件系統的用於超級塊操作的函數集合
struct dquot_operations *dq_op;
struct quotactl_ops *s_qcop;
struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
int s_count;
int s_syncing;
int s_need_sync_fs;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
struct xattr_handler **s_xattr;
struct list_head s_inodes; /* all inodes */
struct list_head s_dirty; /* dirty inodes */
struct list_head s_io; /* parked for writeback */
struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_files;
struct block_device *s_bdev;
struct mtd_info *s_mtd;
struct list_head s_instances;
struct quota_info s_dquot; /* Diskquota specific options */
int s_frozen;
wait_queue_head_t s_wait_unfrozen;
char s_id[32]; /* Informational name */
void *s_fs_info; /* Filesystem private info */
/*
* The next field is for VFS *only*. No filesystems have any business
* even looking at it. You had been warned.
*/
struct mutex s_vfs_rename_mutex; /* Kludge */
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;
/*
* Filesystem subtype. If non-empty the filesystem type field
* in /proc/mounts will be "type.subtype"
*/
char *s_subtype;
};
VFS-索引節點(inode)
- 文件系統處理文件所需要的所有信息都放在稱爲索引節點的數據結構inode中
- 具體文件系統的索引節點是存放在磁盤上的,是一種靜態結構,要使用它,必須調入內存,填寫VFS的索引節點,因此,也稱VFS索引節點是動態節點
- 文件名可以隨時更改,但是索引節點對文件是唯一的,並且隨文件的存在而存在
- 每個inode節點的大小,一般是128字節或256字節
VFS-目錄項對象(dentry)
- 每個文件除了有一個索引節點inode數據結構外,還有一個目錄項dentry數據結構。
- dentry結構代表的是邏輯意義上的文件,描述的是文件邏輯上的屬性,目錄項對象在磁盤上並沒有對應的映像
- inode結構代表的是物理意義上的文件,記錄的是物理上的屬性,對於一個具體的文件系統,其inode結構在磁盤上就有對應的映像
- 一個索引節點對象可能對應多個目錄項對象
VFS-文件對象(file)
- 進程是通過文件描述符來訪問文件的
- Linux中專門用了一個file文件對象來保存打開文件的文件位置,這個對象稱爲打開的文件描述(open file description)
- 文件描述符是用來描述打開的文件的。每個進程用一個files_struct結構來記錄文件描述符的使用情況,這個files_struct結構稱爲用戶打開文件表,它是進程的私有數據
- file結構中主要保存了文件位置,此外,還把指向該文件索引節點的指針也放在其中。file結構形成一個雙鏈表,稱爲系統打開文件表。
VFS數據結構之間的關係
- 超級塊是對一個文件系統的描述
- 索引節點是對一個文件物理屬性的描述
- 目錄項是對一個文件邏輯屬性的描述
- 一個進程所處的位置是由fs_struct來描述的,而一個進程(或用戶)打開的文件是由files_struct來描述的,而整個系統所打開的文件是由file結構來描述
文件系統的註冊和註銷
- 當內核被編譯時,就已經確定了可以支持哪些文件系統,這些文件系統在系統引導時,在 VFS 中進行註冊。
- VFS的初始化函數用來向VFS註冊,即填寫文件註冊表file_system_type數據結構
- 註冊調用register_filesystem()函數
- 註銷即刪除一個file_system_type 結構,需調用 unregister_filesystem()函數
文件系統的安裝
- 安裝一個文件系統實際上是安裝一個物理設備
- 自己(一般是超級用戶)安裝文件系統時,需要指定三種信息:文件系統的名稱、包含文件系統的物理塊設備、文件系統在已有文件系統中的安裝點。
- $ mount -t iso9660 /dev/hdc /mnt/cdrom 其中,iso9660是光驅文件系統的名稱,/dev/hdc是包含文件系統的物理塊設備,/mnt/cdrom就是將要安裝到的目錄,即安裝點。
- 在用戶程序中要安裝一個文件系統則可以調用mount()系統調用。安裝過程主要工作是創建安裝點對象,將其掛接到根文件系統的指定安裝點下,然後初始化超級塊對象,從而獲得文件系統基本信息和相關的操作。
文件系統的卸載
- 如果文件系統中的文件當前正在使用,該文件系統是不能被卸載的
- 否則,查看對應的 VFS 超級塊,如果該文件系統的 VFS 超級塊標誌爲“髒”,則必須將超級塊信息寫回磁盤
- 之後,對應的 VFS 超級塊被釋放,vfsmount 數據結構將從vfsmntlist 鏈表中斷開並被釋放
- 具體的實現代碼爲fs/super.c中的sys_umount()函數