什么是VFS
Vritual Filesystem 是给用户空间程序提供统一的文件和文件系统访问接口的内核子系统。借助VFS,即使文件系统的类型不同(比如NTFS和ext3),也可以实现文件系统之间交互(移动、复制文件等),
- 从用户空间程序的角度来看,VFS提供了一个统一的抽象、接口。这使得用户空间程序可以对不同类型的文件系统发起统一的系统调用,而不需要关心底层的文件系统类型。
- 从文件系统的角度来看,VFS提供了一个基于Unix-style文件系统的通用文件模型(common file model),可以用来表示任何类型文件系统的通用特性和操作。底层文件系统提供VFS规定的接口和数据结构,从而实现对linux的支持。
VFS中的数据结构
VFS是面向对象的,VFS中的数据结构既包含数据也包含对该数据进行操作的函数的指针,虽然是使用C的数据结构来实现,但是思想上和面向对象编程是一致的。
VFS的通用数据模型主要包括4种对象类型:
- Superblock对象,表示一个特定的已挂载文件系统
- Inode对象,表示一个特定的文件
- Dentry对象,表示一个directory entry,即dentry。路径上的每一个单独的组件,都是一个dentry。VFS中没有目录对象,目录只是一种文件。
- File对象,表示进程中打开的文件。
每种对象类型都有着对应的操作操作函数表(相当于对象的方法)
Superblock对象
任何类型的文件系统都要实现Superblock对象,用于存储文件系统的描述信息。Superblock对象通常对应了磁盘上的filesystem superblock 或者 filesystem control block。非磁盘文件系统(比如基于内存的文件系统sysfs)需要动态地生成superblock对象,并将其保存在内存中。
创建、管理、删除superblock对象的代码在fs/super.c中
VFS使用super_block结构体来保存superblock对象。使用alloc_super()函数来创建和初始化superblock对象,文件系统挂载时,文件系统调用alloc_super()从磁盘中读取超级快,并填充super_block结构体.
super_block结构体在<linux/fs.h>中定义的,只给出了部分域
struct super_block
{
struct list_head s_list; /* list of all superblocks */
dev_t s_dev; /* identifier */
unsigned long s_blocksize; /* block size in bytes */
unsigned char s_blocksize_bits; /* block size in bits */
unsigned char s_dirt; /* dirty flag */
unsigned long long s_maxbytes; /* max file size */
struct file_system_type s_type; /* filesystem type */
struct super_operations s_op; /* superblock methods */
struct dquot_operations *dq_op; /* quota methods */
struct quotactl_ops *s_qcop; /* quota control methods */
struct export_operations *s_export_op; /* export methods */
unsigned long s_flags; /* mount flags */
unsigned long s_magic; /* filesystem’s magic number */
struct dentry *s_root; /* directory mount point */
struct rw_semaphore s_umount; /* unmount semaphore */
struct semaphore s_lock; /* superblock semaphore */
int s_count; /* superblock ref count */
int s_need_sync; /* not-yet-synced flag */
atomic_t s_active; /* active reference count */
void *s_security; /* security module */
struct xattr_handler **s_xattr; /* extended attribute handlers */
struct list_head s_inodes; /* list of inodes */
struct list_head s_dirty; /* list of dirty inodes */
struct list_head s_io; /* list of writebacks */
struct list_head s_more_io; /* list of more writeback */
struct hlist_head s_anon; /* anonymous dentries */
struct list_head s_files; /* list of assigned files */
struct list_head s_dentry_lru; /* list of unused dentries */
int s_nr_dentry_unused; /* number of dentries on list */
struct block_device *s_bdev; /* associated block device */
struct mtd_info *s_mtd; /* memory disk information */
struct list_head s_instances; /* instances of this fs */
struct quota_info s_dquot; /* quota-specific options */
int s_frozen; /* frozen status */
wait_queue_head_t s_wait_unfrozen; /* wait queue on freeze */
char s_id[32]; /* text name */
void *s_fs_info; /* filesystem-specific info */
fmode_t s_mode; /* mount permissions */
struct semaphore s_vfs_rename_sem; /* rename semaphore */
u32 s_time_gran; /* granularity of timestamps */
char *s_subtype; /* subtype name */
char *s_options; /* saved mount options */
};
Superblock操作函数
superblock对象中最重要的成员是s_op指针,指向superblock_operations,superblock_operations在<linux/fs.h>中定义,下面仅包含部分的操作函数
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_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 vfsmount *);
int (*show_stats)(struct seq_file *, struct vfsmount *);
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 (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};
这是一个函数表,每个指针都指向了一个对superlbock对象进行操作的函数(