Linux虚拟文件系统(Virtual File System, VFS)是内核中的一个抽象层,它为各种不同的文件系统提供了统一的接口,使得用户空间程序能够以相同的方式访问不同类型的文件系统。
代表一个已挂载的文件系统实例,包含: - 文件系统类型信息 - 块大小 - 操作方法(super_operations) - 指向根目录的dentry
struct super_block {
struct list_head s_list; /* 链表节点 */
dev_t s_dev; /* 设备标识符 */
unsigned long s_blocksize; /* 块大小 */
const struct super_operations *s_op; /* 超级块操作 */
struct dentry *s_root; /* 根目录dentry */
struct file_system_type *s_type; /* 文件系统类型 */
// ...
};
代表文件系统中的一个对象(文件、目录、设备等),包含: - 文件类型(常规文件、目录、符号链接等) - 权限信息 - 大小 - 时间戳 - 操作方法(inode_operations)
struct inode {
umode_t i_mode; /* 文件类型和权限 */
uid_t i_uid; /* 所有者UID */
gid_t i_gid; /* 组GID */
loff_t i_size; /* 文件大小 */
struct timespec i_atime; /* 最后访问时间 */
struct timespec i_mtime; /* 最后修改时间 */
const struct inode_operations *i_op; /* inode操作 */
struct super_block *i_sb; /* 所属超级块 */
// ...
};
代表路径中的一个组成部分,是VFS中重要的缓存机制: - 文件名 - 指向父目录和子目录的链接 - 指向关联的inode - 目录项缓存(dcache)管理
struct dentry {
struct qstr d_name; /* 目录项名称 */
struct dentry *d_parent; /* 父目录 */
struct inode *d_inode; /* 关联的inode */
struct list_head d_subdirs; /* 子目录链表 */
struct dentry_operations *d_op; /* dentry操作 */
// ...
};
代表进程打开的文件: - 文件位置指针 - 访问模式(读、写等) - 指向关联的dentry - 文件操作(file_operations)
struct file {
struct path f_path; /* 包含dentry */
loff_t f_pos; /* 文件位置指针 */
const struct file_operations *f_op; /* 文件操作 */
atomic_long_t f_count; /* 引用计数 */
// ...
};
当内核或模块初始化时,文件系统类型需要注册到VFS:
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; /* 链表指针 */
// ...
};
注册示例:
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
register_filesystem(&ext4_fs_type);
当挂载文件系统时,VFS会: 1. 分配新的super_block 2. 调用特定文件系统的mount方法 3. 建立super_block与文件系统的关联 4. 将super_block加入全局链表
以open()系统调用为例: 1. 用户空间调用open() 2. 陷入内核,调用sys_open() 3. VFS解析路径,查找或创建dentry 4. 查找或创建inode 5. 创建file对象 6. 调用特定文件系统的open方法 7. 返回文件描述符给用户空间
VFS通过一系列操作结构体与具体文件系统交互:
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 *, struct writeback_control *wbc);
// ...
};
struct inode_operations {
int (*create) (struct inode *,struct dentry *, umode_t, bool);
struct dentry *(*lookup) (struct inode *,struct dentry *, unsigned int);
int (*link) (struct dentry *,struct inode *,struct dentry *);
// ...
};
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*open) (struct inode *, struct file *);
// ...
};
常用工具和接口:
- /proc/mounts
- 查看已挂载文件系统
- df
- 查看文件系统空间使用
- dmesg
- 查看文件系统相关内核消息
- /proc/sys/fs
- 调整VFS参数
- strace
- 跟踪文件系统调用
VFS是Linux强大文件系统支持的基础,其设计体现了UNIX"一切皆文件"的哲学,通过抽象层实现了对各种存储设备和特殊文件系统的统一管理。