《Linux内核设计与实现》笔记——VFS
Posted xcy6666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Linux内核设计与实现》笔记——VFS相关的知识,希望对你有一定的参考价值。
关于VFS有一篇很好的博客http://www.ibm.com/developerworks/cn/linux/l-vfs/
建议先阅读本文为基础,然后继续阅读该文章。
VFS,虚拟文件系统,为用户提供了文件和文件系统相关的接口。
这些接口可以跨越各种文件系统和不同介质执行。
VFS提供了一个通用文件系统模型,该模型囊括了任何文件系统的常用功能集和行为。
该模型偏重于Unix风格的文件系统。
数据结构关系
如下图,下图描述了VFS相关数据结构的关系
Unix文件系统
Unix使用了4个和文件系统相关的传统概念:文件,目录项,索引节点,安装点(mount point)
文件
简单的面向字节流的抽象
目录项
文件通过目录组织起来,目录中的每一个部分都是一个目录条目, /home/wolfman/butter , / , home, wolfman , butter 都是目录条目,统称为目录项
索引节点
Unix文件系统,将文件的相关信息和文件本身区分开来。文件控制信息,如权限,拥有者,大小,创建时间等”元数据”,被存储在一个单独的数据结构中,该结构被称为索引节点inode
安装点/挂载点
linux中的磁盘文件系统的入口目录,类似于windows中的用来访问不同分区的C:、D:、E:等盘符。[百度百科词条]
文件系统的信息存储在超级块中,集单独文件信息和文件系统信息于一身。
对于FAT,NTFS这种,虽然也可以在Linux上工作,但必须进行封装。比如:一个文件系统不支持索引节点,也必须在内存中装配索引节点结构体,就像它本身包含一样。
VFS对象及数据结构
超级块对象
- 代表一个具体的已安装文件系统,由super_block结构体表示,定义于
<linux/fs.h>
- 包含操作对象super_operations对象,包括内核针对特定文件系统所能调用的方法,定义于
<linux/fs.h>
- 超级块对象通过alloc_super()函数创建并初始化。在文件系统安装时,文件系统会调用该函数以便从磁盘读取文件系统超级块,并将其信息填充到内存中的超级块对象中
- 各种文件系统都必须实现超级块对象,该对象用于存储特定文件系统信息,通常对应于存放在磁盘特定扇区的文件系统超级块或系统控制块。
super_block
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1242
super_operations
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1604
- 代表一个具体的已安装文件系统,由super_block结构体表示,定义于
索引节点对象
- 代表一个具体文件,包含了内核在操作文件或目录时需要的全部信息,由inode结构体表示,定义于
<linux/fs.h>
- unix风格的文件系统可以直接从磁盘索引节点读入,如果一个文件系统没有索引节点,文件系统需要从磁盘上提取相关信息(没有inode的文件系统通常将文件描述信息作为文件的一部分)
- 索引节点必须在内存中创建,以便于文件系统使用
- 包含操作对象inode_operations对象,包括针对特定文件所能调用的方法,定义于
<linux/fs.h>
- 索引节点代表文件系统中的一个文件(但索引节点仅当文件被访问时,才在内存中创建),也可以是设备或管道这样的特殊文件
inode
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L523
inode_operations
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1559
- 代表一个具体文件,包含了内核在操作文件或目录时需要的全部信息,由inode结构体表示,定义于
- 目录项对象
- 代表一个目录项,是路径的一个组成部分,由dentry结构体表示,定义于
<linux/dcache.h>
- 包含dentry_operations对象,其中包括内核针对特定目录所能调用的方法,定义
<linux/dcache.h>
- VFS把目录当文件对待,路径中的每一个组成部分都由一个索引节点对象表示。为方便查找操作,vfs引入目录项,每个dentry代表路径中的一个特定部分,/bin/vi,这个路径,/,bin,vi(文件)都是目录项对象。
- 目录项也可包括安装点,/mnt/cdrom/foo,构成元素/,mnt,cdrom,foo都是目录项
- vfs在执行目录操作时,如果需要会现场创建目录项对象。
- 目录学没有对应的磁盘数据结构,vfs根据字符串路径名现场创建
- 目录项缓存在目录项缓存dcache中,以加速查找操作
dentry
http://lxr.free-electrons.com/source/include/linux/dcache.h?v=3.11#L106
dentry_operations
http://lxr.free-electrons.com/source/include/linux/dcache.h?v=3.11#L148
- 代表一个目录项,是路径的一个组成部分,由dentry结构体表示,定义于
- 文件对象
- 代表由进程打开的文件,由file结构体表示,定义于
<linux/fs.h>
- 包含file_operations对象,其中包括进程针对已经打开的文件所能调用的方法,定义于
<linux/fs.h>
- 多个进程可以同时打开和操作同一个文件,所以同一个文件可能对应多个文件对象。
- 文件对象仅在进程观点上代表已打开文件,它反过来指向dentry(反过来指向inode),只有目录项才代表打开的实际文件。文件对应的文件对象不是唯一的,但对应的索引节点和目录项对象和文件是唯一的。
file
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L765
file_operations
http://lxr.free-electrons.com/source/include/linux/fs.h?v=3.11#L1528
因为VFS将目录作为一个文件来处理,所以不存在目录对象。
- 代表由进程打开的文件,由file结构体表示,定义于
其他相关数据结构
和文件系统相关的数据结构
- file_system_type
- 用来描述各种特定文件系统,定义于
<linux/fs.h>
,如ext3,ext4 - 每种文件系统,不论是否被安装,都只有一个file_system_type结构体
kernel 3.11
- 用来描述各种特定文件系统,定义于
struct file_system_type {
const char *name;
int fs_flags;
#define FS_REQUIRES_DEV 1
#define FS_BINARY_MOUNTDATA 2
#define FS_HAS_SUBTYPE 4
#define FS_USERNS_MOUNT 8 //Can be mounted by userns root
#define FS_USERNS_DEV_MOUNT 16 // A userns mount does not imply MNT_NODEV
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
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 hlist_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
struct lock_class_key s_vfs_rename_key;
struct lock_class_key s_writers_key[SB_FREEZE_LEVELS];
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
};
- vfsmont
- 用来描述一个安装文件系统的实例,定义于
<linux/mount.h>
- 文件系统被实际安装时,一个vfsmount结构在安装点创建,代表文件系统的实例,换句话说,代表安装点。
- 用来描述一个安装文件系统的实例,定义于
struct vfsmount {
struct dentry *mnt_root;/* root of the mounted tree */
struct super_block *mnt_sb;/* pointer to superblock */
int mnt_flags;
};
和进程相关的数据结构
file_struct
定义于<linux/fdtable.h>
与单个进程相关的信息都包含在内
fs_struct
定义于<linux/fs_struct.h>
包含文件系统和进程相关信息
namespace
定义于<linux/mnt_namespace.h>
使得每一个进程在系统中看到唯一的安装文件系统,不仅是唯一的根目录,而是唯一的文件系统层次结构
Linux存储栈
[ https://www.thomaskrenn.com/en/wiki/Linux_Storage_Stack_Diagram ]
以上是关于《Linux内核设计与实现》笔记——VFS的主要内容,如果未能解决你的问题,请参考以下文章