Linux VFS

翻译自Linux文档中的vfs.txt

介绍

VFS(Virtual File System)是内核提供的文件系统抽象层,其提供了文件系统的操作接口,可以隐藏底层不同文件系统的实现。

Directiry Entry Cache(dcache)

VFS通过open()、stat()这些接口传入的文件名搜索dcache,快速找到文件名对应的dentry。dentry的结构是struct dentry,这只是一个内存结构,不会持久化到磁盘中,仅仅是为了提升性能而已。

dentry cache是整个文件空间的视图,但是大部分情况下并不能同时将所有dentry都加载到内存。VFS会在执行lookup()时,创建还不在内存中的dentry。

The Inode Object

inode代表真实存储在文件系统中的对象,比如文件、目录、FIFO等等。inode的结构是struct inode。一个dentry只能指向一个inode,但一个inode可以被多个dentry指向。

对于块设备的文件系统,inode存储在磁盘上,并在需要的时候拷贝到内存中,修改inode后又会写回磁盘进行持久化。对于伪文件系统,inode保存在内存中。

VFS调用lookup()从指定路径的第一级目录的dentry开始查找对应的inode。lookup()的真实实现是由inode所在的底层文件系统提供的。

The File Object

打开一个文件实际就是创建一个file对象。file的结构是struct file,其有指向一个dentry的指针,和一组操作file的函数指针。这些信息是从inode中获取的。在打开文件的最后,file会被加入当前进程的文件描述符表中。

用户的读、写、关闭文件都通过fd进行,内核会可以根据fd获取到对应的file对象,这些操作最终都会调用到底层文件系统提供的函数。

注册和挂载文件系统

注册和注销文件系统的函数如下

#include <linux/fs.h> extern int register_filesystem(struct file_system_type *); extern int unregister_filesystem(struct file_system_type *);

当挂载文件系统时,VFS会调用底层文件系统指定的mount()函数,mount()会返回一个dentry作为文件系统的根目录。所有已挂载的文件系统,可以在/proc/filesystems中看到。

struct file_system_type

该结构用于描述文件系统,自内核2.6.30,有如下定义

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"等。

fs_flags:比如FS_REQUIRES_DEV、FS_NO_DCACHE等一些标志。

mount:挂载文件系统时调用。

kill_sb:卸载文件系统时调用。

owner:在大部分情况下,应当初始化为THIS_MODULE。

next:应当初始化为NULL。

s_lock_key,s_umount_key:用于检查死锁。

mount()的参数如下

struct file_system_type* fs_type:描述文件系统,其中部分底层文件系统初始化。

int flags:挂载的标志,如FS_REQUIRES_DEV,FS_NO_DCACHE等。

const char *dev_name:挂载的设备名。

void *data:任意的选项,通常是ASCII字符串。

mount()成功时,要求加锁并获得superblock的活动引用,返回dentry(可以是子目录的dentry),失败时返回ERR_PTR(error)。

grab_super()是获取活动引用的函数,即让spuer_block::a_active加1

mount()会创建一个superblock,其结构是struct superblock。struct superblock中有一个指向struct super_operations的指针s_op,其由一系列操作文件系统的函数指针组成。

VFS提供了如下方法挂载不同类型的文件系统

mount_bdev():挂载基于块设备的文件系统。

mount_nodev():挂载不基于设备的文件系统。

mount_single():挂载共享实例的文件系统。

这些函数都有一个入参int (*fill_super)(struct super_block *, void *, int),其用于初始化struct superblock的部分字段。

fill_super的参数如下

struct super_block *sb:指向superblock。

void *data:mount的参数,通常是一个ASCII字符串,需要自行解析。

int silent:确定是否输出错误信息。

The Superblock Object

一个superblock代表了一个已挂载的文件系统。

struct super_operations

VFS通过struct super_operations操作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); };

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzddjg.html