標籤:
虛擬檔案系統(virtual file system),別名虛擬檔案系統開關,是linux中的一個軟體層,向使用者空間提供檔案系統操作介面。
VFS包含的系統調用包括open(2)、stat(2)、read(2)、write(2)、chmod(2)等等,這些系統調用在進程環境中執行。下面幾個重要的資料結構是VFS(虛擬檔案系統中涉及到的資料結構):
1、Directory Entry Cache(dcache)
VFS實現了系統調用open(2)、stat(2)、chmod(2),和其他類似的檔案系統調用。用於這些系統調用中的參數被VFS用來進行directory entry cache的對象搜尋,其中directory entry cache有多個名字,比如dentry cache或者dcache。 通過dentry cache提供了一種快速尋找機制,可以快速的根據路徑名字找到具體的dentry。需要特別說明的是:dentry是存在於記憶體中的,不會儲存到磁碟上進行非揮發性儲存體的。
2、inode 對象
每一個dentry對象都有一個指標指向具體的inode對象。inode是檔案系統的對象,比如正規檔案(regular file)、目錄(directory)、FIFO(管道)。這些inode對象存在於磁碟(塊裝置檔案檔案系統)或者記憶體(linux下的偽檔案系統procfs)。如果是存在於磁碟上的inode對象則需要載入到記憶體中去,當發生的改變需要儲存到磁碟上去。一個inode對象可能有多個dentry對象指向它(因為linux下實現了硬串連特性)。
為了尋找一個具體的inode對象需要在父目錄的inode上執行lookup操作。而具體的lookup方法是由inode存放的檔案系統具體的實現,這個操作是由具體的檔案系統進行初始化。一旦VFS擁有具體的dentry對象的時候,很多系統調用就可以迅速完成,比如stat(2)系統調用,它就是擷取inode上的資料,根據dentry上的指標可以迅速的找到inode對象。
3、File對象
開啟一個檔案還需要另外一個操作:分配一個File結構的對象(這是linux核心端的檔案描述符的實現)。新申請的File對象初始化了一個指標指向dentry對象和多個檔案操作函數(比如read、write、mmap等操作)。File資料結構放在這個進程的檔案描述表中(file descriptor table)。
使用者空間的read、write等操作都是通過使用者空間態(userspace file descriptor)的描述符獲得正確的File結構,然後調用File結構中的具體的方法。只要檔案處於開啟狀態,linux核心中就有對應的dentry對象,自然也有對象的inode對象。
4、檔案系統對象(filesystem)
登記和卸載一個檔案系統使用下面的函數調用。
#include <linux/fs.h>
extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);
傳入的參數struct file_system_type描述了具體的檔案系統。當發出一個命令,需要在你的名字空間的一個目錄上掛載一個檔案系統的時候,VFS會調用具體檔案中的mount方法。當mount操作完成之後,會返回一個struct dentry對象,這個時候會建立一個vfsmount對象,用於指向這個dentry對象,同時這個vfsmount對象會添加到這個掛載點上。所以當路徑解析到達這個目錄的時候,會跳轉到這個vfsmount指向的檔案系統中去。
在/proc/filesystems下可以觀察到所有掛載的檔案系統。
以下是file_system_type結構:
struct file_system_type {
const char *name;
int fs_flags;
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
};
name:檔案系統的名字,當前支援的檔案名稱字有“ext2”,“ext3”,“ext4”,“msdos”等
fs_flags:一些標誌,比如:FS_REQUIRES_DEV, FS_NO_DCACHE
mount:重要的field,當一個filesystem執行個體化的時候需要具體的filesystem的mount方法
5、superblock對象
一個superblock(超級塊)對象代表了一個掛載的檔案系統。
下面是關於超級塊的操作的資料結構:
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *, int flags);
int (*write_inode) (struct inode *, int);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_fs) (struct super_block *);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct dentry *);
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
int (*nr_cached_objects)(struct super_block *);
void (*free_cached_objects)(struct super_block *, int);
};
所有的方法都沒有lock來維持,這說明了這些方法只可以在一個進程上下文中執行,不能在中斷上下文中執行。
6、address space對象
address_space對象用於對page cache中的page進行分組和管理。它可以用來跟蹤一個檔案中的page cache和一個檔案中映射到進程地址空間中的檔案地區。
address space提供了大量有顯著特徵的服務,比如根據通過地址尋找page,追蹤標誌為Dirty或者WriteBack的page。
Further Reading:
1.Creating Linux virtual filesystems. 2002. http://lwn.net/Articles/13325/
2.A tour of the Linux VFS by Michael K. Johnson. 1996. http://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html
linux的虛擬檔案系統VFS