Linux文件存储抽象VFS

发表于:2018-3-21 09:49

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:OshynSong    来源:CSDN博客

分享:
  Directory entry
  dentry是用来记录具体的文件名与对应的inode间的对应关系的,同时可以用来实现硬链接、缓存、多级目录等树状文件系统的特性。VFS的dentry设计上就是为了实现整个文件系统树状层次结构的,每个文件系统拥有一个没有父dentry的根目录(root dentry),这个dentry会被superblock引用,用来作为进行树形结构的查找入口。其余的所有dentry都是有唯一的父dentry,并可以由若干个孩子dentry。示例:对于一个文件"/home/user/a”,会存在“/”、“home”、“user”、“a”四个dentry,依次构成父子关系,每个dentry也都有一个inode与之关联,存储了具体的数据。
  dentry没有在磁盘等底层持久化存储设备上存储,是一个动态创建的内存数据结构,主要是为了构建出树状组织结构而设计,用来进行文件、目录的查找。dentry创建之后会被操作系统进行缓存,目的是为了提升对文件系统进行操作的性能。dentry的结构如下示意,具体定义于“<linux/dcache.h>”。
  其中最重要的有两个字段,一个是d_inode指针指向了当前dentry关联的inode。另一个就是d_op字段,指向了一系列dentry支持的操作的集合。典型的dentry支持的操作集合如下:
struct dentry_operations {
int (*d_revalidate)(struct dentry *, int);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
};
  dentry在需要使用时动态创建,并会被缓存。每个dentry有三种状态:
  used:与一个inode关联,正处于被VFS使用的状态,不能被损坏和丢弃
  unused:与inode关联,但处于被缓存状态,没有被VFS使用
  negative:没有与具体的inode关联(相当于是一个无效的路径)
  dentry由于会被动态创建,为了提升系统性能,设计了一个dentry cache进行缓存,包括三个部分:
  used dentries 链表:记录每个正在使用的dentry,将其关联的inode的i_dentry字段指向的dentry链表连接起来形成一个dentry链表的链表
  LRU双向环链表:用于维护unused和negative状态的dentry对象,从头部插入,离头部越近就是最近访问过的。当需要删除dentry时,从队列尾部删除最旧的dentry
  hash table和hash function:用来快速查询一个给定的路径到dentry对象
  File
  文件对象是打开一个具体文件之后创建的一个内存数据结构,与具体的进程和用户相联系。一个文件对象包括的内容就是编程语言支持设置的各种文件打开的flag、mode,文件名称、当前的偏移等,其中非常重要的一个字段就是f_op,指向了当前文件所支持的操作集合。
struct file {
struct dentry *f_dentry;
struct vfsmount *f_vfsmnt;
struct file_operations *f_op;
mode_t f_mode;
loff_t f_pos;
struct fown_struct f_owner;
unsigned int f_uid, f_gid;
unsigned long f_version;
...
}
  基本的操作集合如下,这也是使用应用程序可感知到的一系列接口。
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
};
  VFS抽象组件间的关系
  从用户角度来看VFS的时候,可以通过下图很容易的理解各个抽象组件间的协作关系:
  每个打开的文件对用户来说有一个文件描述符,也就是VFS抽象的file object。file object指向一个dentry,dentry指向新的dentry或一个inode,inode最终代表了一个具体存储设备上的数据。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号