VFS框架

VFS的目的是屏蔽底层的具体的文件系统(如Ext2/Ext3/NTFS/FAT...)的细节,向上(用户空间,进程空间)提供统一的借口。

VFS向上提供相关的文件操作系统调用(如mountreadwrite...),重点学习其中的几种数据结构,并分析其与磁盘上以及内存中(往往是磁盘上的映射)的具体文件系统的关联(以Ext3为分析)。

1.file_system_type(VFS文件系统对象)

结构体定义参见fs.h。对于Ext3文件系统的初始化为:

static struct file_system_type ext3_fs_type = {

.owner = THIS_MODULE,//当前调用模块

.name = "ext3",

.get_sb = ext3_get_sb,//该函数是重头戏

.kill_sb = kill_block_super,

.fs_flags = FS_REQUIRES_DEV,

};

这个东西指明了VFS对应的下层的具体文件系统的类型,属于文件系统的驱动范畴。每次注册一个新的文件系统都要使用内核函数register_filesystem()来注册,相应的操作就是建立file_system_type结构体并且把该结构体链在以全局变量file_systems指向的链表里。具体的操作可见filesystems.c

2.super_block(VFS超级块--sb)

重点关注其中的相关结构体:(参见fs.h)

Struct super_block{

.......

struct list_head s_list;//结合Ext3分析可猜的所有的sb都是链在一起的

unsigned char s_dirt;//值得注意的是Ext3_sb_info也即是Ext3的内存中的sb映射没有脏位,所以一般是修改VFSsb然后向磁盘写回的时候与Ext3_super_block同步。

struct file_system_type *s_type;//挂载的文件系统的信息,见上面。

const struct super_operations *s_op;//针对下层的文件系统的相关的操作。

struct dentry *s_root;//指向根目录的dentry

.......

void  *s_fs_info;//指向具体的文件体统的sb的内存映射的指针,对于Ext3来说指向的就是Ext3_sb_info.

那么内核中到底是如何使用磁盘上的sb来对VFSsb以及内存中的sb映射进行初始化的呢?

于是针对file_system_type中的Ext3_get_sb()函数分析。跟入函数会发现调用了Ext3_fill_super()函数。该函数首先建立了内存中的Ext3_sb_info的结构,然后把VFSsb中的指针指向该结构,然后请求磁盘驱动程序读取磁盘超级块Ext3_super_block的内容到buffer_head结构体中(该结构体中使用radix_tree分配相应的page),再根据Ext3_super_block信息初始化Ext3_sb_info中信息,然后对VFSsuper_block进行初始化,其中尤其注意sb->s_op = &ext3_sops;即指明了VFS super_block对底层文件系统的操作。

3.Inode

同样这个inode与底层具体文件系统的ext3_inode有很大的差别。目的是向上对文件的操作提供一个接口。

在上面的Ext3_fill_super函数中有一句:

root = ext3_iget(sb, EXT3_ROOT_INO);初始化了VFS根目录的inode也就是我们常见的“/”的inodeExt3_iget函数则是根据inode号对内存中的sb映射进行索引找到对应的文件系统ext3_inode_info,并把ext3_inode_info转化为VFSinode,然后根据标志位判断是否是目录还是普通文件来设置相关的操作。(具体可见inode.c中的ext3_iget

4.VFS文件对象file结构体。

该文件才是我们看到的真正意义上的“文件”,在我们使用open等函数的时候会临时创建该结构体,其本身在内存或磁盘上没有映射。

该结构体中含有目录结构体(见下面)dentry f_dentry也就是文件的所在目录信息,其中包含了对应的inodefile_operations和一个很重要的struct address_space *f_mapping。该结构体中使用radix_tree来管理文件中的内容,该结构体中还含有inode的信息。

5.VFS目录对象结构体dentry

每一个目录都对应一个dentry里面含有该目录的inodeVFS中的文件和目录都有inode对应,只不过文件inode后面的地址中可以访问的是数据,而目录inode指向的数据中含的则是目录下的目录或者文件。

注意所有的dentry都使用链表连接在一起,可以从sb->rootdentry->各级的dentry。并且每个dentry都有指向sb的指针。具体参见dentry结构(dcache.h)。

6.文件系统和进程的关联:

比如对一个文件进行操作(如openread...),在current->task_struct中有2个指针:

Struct fs_struct *fs;

Struct files_struct *files;

Fs指向的结构体中含有两个path结构体,分别为pwd(当前目录)和root(根目录)。Path结构体中则是dentry结构体和挂载信息的结构体。

Files指向的结构体中含有file *fd_array[]也就是对所有file结构的一个索引,用户态程序使用的fd

这就是今天早上内容的总结,大致对照这些结构体相关的文件的路径的定位,文件的修改也就很好理解了。参见ULK

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值