虚拟文件系统

文件系统基础知识

1.文件类型

普通文件(regular file):包括文本文件和二进制文件。通过open或creat系统调用函数可以创建一个普通文件。

目录文件(directory file):也称为目录,一个目录的内容即为该目录下的文件和其他子目录。通过mkdir命令可创建一个目录。通过ls -l某个目录文件时,可以看到该文件的属性的第一项为d,即表示目录文件。

设备文件(device file):Linux将硬件设备也当作文件来处理,通过mknod命令可以创建一个设备文件。通常设备文件分为字设备文件(character special file),比如键盘和鼠标等;还有块设备文件(block special file),比如硬盘和光驱等。

链接文件(symbolic link):也称为符号链接,通过ln命令可以创建一个符号链接。符号链接文件本身就是一个文件,这种文件的内容则是另一个文件(即源文件)的路径。对符号链接进行读写等基本操作时,系统会自动将其转化为对源文件的相应操作。通过ls -l某个符号链接文件时,可以看到文件属性的第一项为l,即表示目录文件。

管道文件(pipe):用于进程间通信,也称为FIFO文件。通过系统调用pipe可以创建一个管道。管道文件在使用上和普通文件没有什么太大的区别,只不过这种文件不像普通文件那样存储与磁盘上,而是存储在内存中。

套接字文件(socket):主要用于网络通信,也可以用于一台主机上的进程间通信。

2.Linux文件结构

Linux采用树型结构将所有文件组织起来,也就是说,每一个Linux系统就只对应一个这样的树型结构。windows操作系统也采用树型结构,但却是每个分区对应一个树型结构。下面对Linux根目录下的一些常见子目录进行说明:

/bin:存放二进制的可执行的命令文件,我们通常所使用的命令就是来自这里。比如ls,cat等。

/sbin:存放系统管理命令的目录,即为使用前要加sudo的那些命令,比如fdisk等。

/mnt:存放用户临时安装其他文件系统的目录。

/dev:存放设备文件的目录。

/etc:存放系统管理和配置文件的目录。

/home:系统中所有用户主目录的汇总。通过/home/username可以访问某个用户的主目录。

/tmp:公共的临时文件目录。相对的,每个用户在其主目录下也有私有的临时文件目录。

/lib:标准程序设计库,又叫做动态链接共享库。

/proc:这个目录存在与内存中,不占用磁盘空间。该目录存放的是对内存的一次映像,我们每打印一次/proc目录,显示的就是当前内存的状态。

虚拟文件系统

Linux可支持数十种文件系统,不同的文件系统可以同时共存于一个系统之中。这些不同类型的文件系统并不是各自封闭的,而很可能会进行文件复制和移动等。比如,我的PC中装有双系统(比如ubuntu+winXP),现在我要将XP系统E盘中的test.doc文件拷贝到ubuntu系统中的主目录下。我们知道,XP的文件系统类型是FAT,而Linux主目录的文件系统类型是ext3,我们如何使用一种统一的“语言”来支持这种不同文件系统上文件的移动和复制?虚拟文件系统(Virtual FileSystem,VFS)就扮演的这样的角色,即支持跨越不同文件系统或存储设备的文件操作。

VFS是在各种具体的文件系统之上建立了一个抽象层,它屏蔽了不同文件系统间的差异。它之所以可以将各种文件系统纳入其中,是因为它提供了一个通用的文件系统模型。在内核中,这个通用的模型具体的表现为一组统一的抽象接口和数据结构。每个文件系统都必须实现这些统一接口,并在组织结构上与该模型保持一致。

VFS相当于一个万能插销座,具体的文件系统相当于插销座内部的电路实现。不管是两头插销还是三头插销,甚至未来出现的单头插销都可以使用这个万能的插座,使用根本不必考虑这个插座内部是如何实现的。

关于VFS更加全面的解说可以看这里

VFS中的数据结构

上面说到,VFS是通用的文件系统模型。那么,这个通用性具体如何表现出来?VFS主要通过一组数据结构来描述文件对象。其中有四个基本的结构体:

超级块(struct super_block):它描述一个已安装了的文件系统。

索引结点(struct inode):它描述一个文件。

目录项(strcut dentry):它描述文件系统的层次结构。一个完整路径的每个组成部分都是一个目录项。比如打开/home/edsionte/code/hello.c时,内核分别为/,home/,edsionte/,code/,hello.c创建相应的目录项。

文件(struct file):它描述一个已被进程打开的文件。

VFS采用面向对象的思想,在上述每一个结构体中即包含描述每个文件对象属性的数据,又包含对这些数据进行操作的函数指针结构体。也就是说,上述四个基本的结构体中,每一个结构体中又嵌套了一个子结构体,这个子结构体包含了对父结构体进行各种操作的函数指针。

上述文字是对VFS主要的几个结构体大致的说明。下文中,将从代码的角度分析这些结构体。

目录 1 虚拟文件系统概述 5 1.1 通用文件模型 7 1.2 VFS所处理的系统调用 9 2 虚拟文件系统架构 11 2.1 VFS对象数据结构 11 2.1.1 超级块对象 11 2.1.2 索引节点对象 15 2.1.3 文件对象 18 2.1.4 目录项对象 22 2.2 把Linux中的VFS对象串联起来 24 2.2.1 与进程相关的文件 25 2.2.2 索引节点高速缓存 29 2.2.3 目录项高速缓存 30 2.2.4 VFS对象的具体实现 32 2.3 文件系统的注册与安装 38 2.3.1 文件系统类型注册 38 2.3.2 文件系统安装数据结构 41 2.3.3 安装普通文件系统 52 2.3.4 分配超级块对象 58 2.3.5 安装根文件系统 60 2.3.6 卸载文件系统 65 2.4 路径名的查找 66 2.4.1 查找路径名的一般流程 67 2.4.2 父路径名查找 82 2.4.3 符号链接的查找 84 2.5 VFS系统调用的实现 88 2.5.1 open()系统调用 88 2.5.2 read()和write()系统调用 96 2.5.3 close()系统调用 97 3 第二扩展文件系统 99 3.1 Ext2磁盘数据结构 101 3.1.1 磁盘超级块 102 3.1.2 组描述符和位图 105 3.1.3 磁盘索引节点表 105 3.2 VFS接口数据结构 110 3.2.1 Ext2 超级块对象 110 3.2.2 Ext2 的索引节点对象 121 3.2.3 创建Ext2文件系统 124 3.2.4 Ext2的方法总结 126 3.3 Ext2索引节点分配 129 3.3.1 创建索引节点 130 3.3.2 删除索引节点 143 3.4 Ext2数据块分配 144 3.4.1 数据块寻址 145 3.4.2 文件的洞 147 3.4.3 分配数据块 148 4 页面高速缓存 160 4.1 页高速缓存数据结构 160 4.1.1 address_space对象 161 4.1.2 基树 164 4.2 高速缓存底层处理函数 166 4.2.1 查找页 166 4.2.2 增加页 168 4.2.3 删除页 173 4.3 文件系统与高速缓存 175 4.3.1 缓冲头数据结构 175 4.3.2 分配块设备缓冲区页 178 4.3.3 释放块设备缓冲区页 184 4.4 在页高速缓存中搜索块 185 4.4.1 __find_get_block()函数 185 4.4.2 __getblk()函数 188 4.4.3 __bread()函数 190 4.5 把脏页写入磁盘 191 4.5.1 pdflush内核线程 192 4.5.2 搜索要刷新的脏页 193 4.5.3 回写陈旧的脏页 196 5 文件读写 199 5.1 系统调用VFS层的处理 200 5.2 第二扩展文件系统Ext2层的处理 201 5.2.1 Ext2的磁盘布局 202 5.2.2 Ext2的超级块对象 206 5.2.3 Ext2索引节点对象的创建 210 5.2.4 Ext2索引节点对象的读取 218 5.2.5 Ext2层读文件入口函数 225 5.3 页高速缓存层的处理 237 5.3.1 创建一个bio请求 238 5.3.2 得到文件的逻辑块号 244 5.3.3 普通文件的readpage方法 251 5.3.4 块设备文件的readpage方法 252 5.3.5 文件的预读 260 5.4 通用块层的处理 264 5.4.1 块设备的基础知识 265 5.4.2 通用块层相关数据结构 269 5.4.3 提交I/O传输请求 271 5.4.4 请求队列描述符 273 5.5 块设备I/O调度层的处理 281 5.5.1 块设备的初始化 284 5.5.2 建立块设备驱动环境 288 5.5.3 关联block_device结构 295 5.5.4 为设备建立请求队列 306 5.5.5 块设备I/O调度程序 311 5.5.6 真实的I/O调度层处理 321 5.6 块设备驱动层的处理 330 5.6.1 scsi总线驱动的初始化 330 5.6.2 scsi设备驱动体系架构 342 5.6.3 scsi块设备驱动层处理 347 5.6.4 scsi命令的执行 369 5.6.5 scsi命令的第一次转变 372 5.6.6 scsi命令的第二次转变 380 5.7 写文件 384 5.7.1 generic file_write函数 384 5.7.2 普通文件的prepare_write方法 386 5.7.3 块设备文件的prepare_write方法 387 5.7.4 将脏页写到磁盘 388 6 直接I/O与异步I/O 391 6.1 直接I/O 391 6.2 异步I/O 393 6.2.1 Linux 2.6中的异步I/O 394 6.2.2 异步I/O环境 394 6.2.3 提交异步I/O操作 395
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值