《Linux内核设计与实现》读书笔记(十三)

虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备。

虚拟文件系统本身是linux内核的一部分,是纯软件的东西,并不需要任何硬件的支持。

主要内容:

1. 虚拟文件系统的作用

虚拟文件系统(VFS)是linux内核和存储设备之间的抽象层,主要有以下好处。

– 简化了应用程序的开发:应用通过统一的系统调用访问各种存储介质

– 简化了新文件系统加入内核的过程:新文件系统只要实现VFS的各个接口即可,不需要修改内核部分

2. 虚拟文件系统的4个主要对象

虚拟文件中的4个主要对象,具体每个对象的含义参见如下的详细介绍。

2.1 超级块

超级块(super_block)主要存储文件系统相关的信息,这是个针对文件系统级别的概念。

它一般存储在磁盘的特定扇区中,但是对于那些基于内存的文件系统(比如proc,sysfs),超级块是在使用时创建在内存中的。

超级块的定义在:<linux/fs.h>

/* * 超级块结构中定义的字段非常多, * 这里只介绍一些重要的属性 */struct super_block {super_operations *s_op; dentry*s_root;mutexs_lock;s_count;list_head s_inodes;mtd_info*s_mtd;fmode_ts_mode;};/* * 其中的 s_op 中定义了超级块的操作方法 * 这里只介绍一些相对重要的函数 */struct super_operations {(*destroy_inode)((*dirty_inode) ((*write_inode) ((*drop_inode) ((*delete_inode) ((*put_super) ((*write_super) ((*sync_fs)((*statfs) ((*remount_fs) ((*clear_inode) ((*umount_begin) (};

2.2 索引节点

索引节点是VFS中的核心概念,它包含内核在操作文件或目录时需要的全部信息。

一个索引节点代表文件系统中的一个文件(这里的文件不仅是指我们平时所认为的普通的文件,还包括目录,特殊设备文件等等)。

索引节点和超级块一样是实际存储在磁盘上的,当被应用程序访问到时才会在内存中创建。

索引节点定义在:<linux/fs.h>

/* * 索引节点结构中定义的字段非常多, * 这里只介绍一些重要的属性 */struct inode {list_head i_list;list_head i_sb_list; list_head i_dentry; unsigned atomic_ti_count;unsigned uid_ti_uid;gid_ti_gid;timespeci_atime; timespeci_mtime; timespeci_ctime; inode_operations *i_op; file_operations *i_fop; super_block *i_sb;address_space *i_mapping;address_space i_data;unsigned *i_private;};/* * 其中的 i_op 中定义了索引节点的操作方法 * 这里只介绍一些相对重要的函数 */struct inode_operations {(*create) (struct inode *,struct dentry *,int, struct nameidata *);dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);(*link) (struct dentry *,struct inode *,struct dentry *);* (*follow_link) (struct dentry *, struct nameidata *);(*put_link) (struct dentry *, struct nameidata *, void *);(*truncate) (struct inode *);};

2.3 目录项

和超级块和索引节点不同,目录项并不是实际存在于磁盘上的。

在使用的时候在内存中创建目录项对象,其实通过索引节点已经可以定位到指定的文件,

但是索引节点对象的属性非常多,在查找,网站空间,比较文件时,直接用索引节点效率不高,所以引入了目录项的概念。

路径中的每个部分都是一个目录项,虚拟主机,比如路径: /mnt/cdrom/foo/bar 其中包含5个目录项,/ mnt cdrom foo bar

每个目录项对象都有3种状态:被使用,未使用和负状态

– 被使用:对应一个有效的索引节点,并且该对象由一个或多个使用者

– 未使用:对应一个有效的索引节点,但是VFS当前并没有使用这个目录项

– 负状态:没有对应的有效索引节点(可能索引节点被删除或者路径不存在了)

目录项的目的就是提高文件查找,比较的效率,所以访问过的目录项都会缓存在slab中。

slab中缓存的名称一般就是 dentry,可以通过如下命令查看:

[wangyubin@localhost kernel]$ sudo cat /proc/slabinfo | grep dentrydentry: tunables : slabdata

目录项定义在:<linux/dcache.h>

dentry {atomic_t d_count;unsigned spinlock_t d_lock;d_mounted;inode *d_inode; hlist_node d_hash; dentry *d_parent; qstr d_name;list_head d_lru;* d_child and d_rcu can share memory*/union { rcu_head d_rcu;} d_u;list_head d_alias; unsigned dentry_operations *d_op; super_block *d_sb; *d_fsdata;unsigned }; dentry_operations {(*d_revalidate)(struct dentry *, struct nameidata *);(*d_hash) (struct dentry *, struct qstr *);(*d_compare) (struct dentry *, struct qstr *, struct qstr *);(*d_delete)(struct dentry *);(*d_release)(struct dentry *);(*d_iput)(struct dentry *, struct inode *);char *(*d_dname)(struct dentry *, char *, int);};

2.4 文件对象

文件对象表示进程已打开的文件,从用户角度来看,我们在代码中操作的就是一个文件对象。

文件对象反过来指向一个目录项对象(目录项反过来指向一个索引节点)

其实只有目录项对象才表示一个已打开的实际文件,虽然一个文件对应的文件对象不是唯一的,但其对应的索引节点和目录项对象却是唯一的。

文件对象的定义在: <linux/fs.h>

却坐在不足一平米的椅子上。

《Linux内核设计与实现》读书笔记(十三)

相关文章:

你感兴趣的文章:

标签云: