什么是虚拟文件系统?
- linux会实现多种基于磁盘的文件系统,比如ext4/xfs等,为了支持不同的磁盘文件系统,且多个磁盘文件系统互相访问,Linux内核在用户进程和磁盘文件系统系统之间引入一个臭小抽象层,这个就是虚拟文件系统(vfs)。
虚拟文件(vfs)系统有什么作用?
- vfs一方面用来提供操作文件、目录以及其他对象的统一方法;另外一方面,它必须能够与各种给出具体磁盘文件系统的实现达成妥协。
文件系统分为哪些类型?
- 目前文件系统基本可以分为三类,第一类是基于磁盘的文件系统,例如xfs.第二类是内核虚拟文件系统,是一种使用应用程序与用户进程通信的方法,内核的proc文件系统就是典型实现;第三种是网络文件系统,计算机通过网络连接到本地计算机,具体的数组组织和处理都是由远程计算机内核进行。
inode有什么用?
- 在处理文件时候,内核空间和用户空间使用的对象不同;对于用户程序而言,一个文件是有文件描述符标识,文件描述符是一个整数,进程操作文件都是通过这个文件描述符。文件描述符是在打开文件时候内核给进程分配的,有效期仅仅是在该进程的生命周期内;对于内核而言,处理文件的核心是inode,每个文件和 目录都有唯一的一个对应的inode,其中包含元数据(访问时间、修改时间、创建时间)和指向文件数据的指针,但是inode不包括文件名。
- inode 对于文件实现是一个主要概念,但是inode也用于实目录。在另外一个角度来讲,目录也是一种特殊的文件。inode的成员总体可以分为两类,第一类是描述文件状态的元数据;第二类是保存实际文件内容的数据段
内核如何查找一个文件?
- 比如我们查找
/usr/bin/go
这个文件,/
表示根目录,是由一个inode表示,该inode的数据段不包含普通文件的数据,而是根目录下面的各个目录项,这些目录项可能代表文件或者目录,每个目录项(dentry)是由一个inode和文件或者目录名组成.目录项中的inode存储该目录下文件或者目录名称和对应的inode。 - 根据
/
目录inode中查找子目录user
的inode,这会读取/
目录的inode的数据段,直到找到usr
目录项(如果查找失败,返回错误即可)。接着读取usr
的inode查找子目录bin
的目录项,读取bin
目录的inode,查找go
这个文件所在的inode,读取go
文件的元数据返回即可。
- 在这次查找过程中最后一个inode是具体文件,其他三个都是目录。目录的inode存储的内容是目录项(dentry=inode 文件或者目录名称)的列表.
dentry有什么作用?
- dentry也也叫做目录项,用来建立文件名和inode之间的关联每个dentry实例形成网络层次关系,与文件系统的结构形成一定的映射关系。我们执行文件查找命令时候,内核是通过vfs层的detnry来进行查找,同时内核提供dentry cache(d_cache)来缓存dentry,采用LRU策略来管理缓存,设置dcache(dentry cache)目录是为了加速查找inode.在vfs中dentry定义如下:
struct dentry {
/* RCU lookup touched fields */
unsigned int d_flags; /* protected by d_lock */
seqcount_spinlock_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
// 父节点目录的dentry指针
struct dentry *d_parent;
// 文件名称超过一定长度时候,文件名称存储在这里
struct qstr d_name;
// 指向关联的inode对象
struct inode *d_inode;
// 当文件名称不超过16个字符时候,文件名称存储在d_iname中
unsigned char d_iname[DNAME_INLINE_LEN];
// 提供各种dentry对象操作的函数结构指针
const struct dentry_operations *d_op;
// dentry对象所属文件系统超级块的实例
struct super_block *d_sb;
// 实际文件系统的私有数据
void *d_fsdata;
// 父目录节点的下所有子目录或者文件的dentry
struct list_head d_child; /* child of parent list */
// 子目录或者文件dentry的链表
struct list_head d_subdirs; /* our children */
/*
* d_alias and d_rcu can share memory
*/
union {
// 用于将dentry连接到inode的i_dentry指针
struct hlist_node d_alias;
// 哈哈西散列表
struct hlist_bl_node d_in_lookup_hash;
} d_u;
} __randomize_layout;