Linux VFS

本文将描述Linux内核中的VFS(Virtual File System)。对于VFS这个概念其实非常容易理解,无非是一个抽象的统一接口:它定义了所有文件系统都支持的基本的和概念上的接口和数据结构,这样就在用户上层看来,无论对何种文件系统都拥有统一的接口,和操作方式。其实,对VFS的理解停留在这个层面上对于掌握其思想已经够用了,剩下要讨论的也就是它的实现和一些和进程和文件系统的外延部分了。

目前总有一些困惑就是对于一个问题或者概念的抽象层次的把握,比如对于一个软件工程师,他需要对计算机有所了解,不过不可能做到样样深入,比如内存,我们需要知道它是用来存储临时数据的,性能介于寄存器和磁盘之间,我们不需要知道它是如何设计的,经过多少工艺制作而成的。所以有的时候,你对一个问题的抽象层次决定着你对问题的把握。因为不可能完全把问题从最底层剖析,我们只能在我们所熟知的层面或者说是我们所需要的层面去剖析问题。

话题有些扯远了,不过我想表达的是,如果只是想知道VFS是什么东西的话,第一段的几句话我认为已经够用了。那么继续深入的意义究竟何在呢?或者说目的究竟何在呢?我认为有这么几点吧:

1. 文件系统的内存表示

文件系统一方面定义了如何在磁盘上组织用户的数据信息,那如何高效的读写管理文件就是内核要考虑的事情了。VFS就是linux用来管理文件系统的方式(当然不仅仅是vfs,还牵涉到I/O等等方面)。

2. VFS设计

VFS是一个比较成功的例子,它为所有的文件系统提供统一的接口,这个思想和设计可以被借鉴到其他地方。另外VFS用到的面向对象的概念,所以这又是一个c语言实现的面向对象范例。

3. 算法

对dcache中用到LRU. slab存储dentry

 

好了,有了目标,那接下来就是各取所需了。

文件系统的内存表示

这个标题有点起大了,更贴切的应该说是vfs中的一些数据结构。

首先来说一下Linux中用到的和文件系统相关的传统抽象概念:文件,目录项,i-node,mount point

这里我想从i-node说起,因为i-node本身的概念使得文件和目录项并不是我们通常说想象的那样了。i-node是*nux文件系统中用来表示文件和目录的数据结构。也就是说通过i-node我们可以知道文件的所有信息。具体的描述可以参考另一篇文章:Ext3 File system Disk Layout

那么如果i-node已经代表文件和目录,那么这里的文件和目录项又是什么意思呢?

文件对象

我们先说文件对象,这里的文件对象是指打开的文件在内存中的表示。该对象由open()系统调用创建,由close()系统调用销毁。也就是说一个文件系统中的文件可能存在多个对应的文件对象。它其实是用在进程的角度的,多个进程可以同时打开同一个文件,不过打开的文件会有自己特有的状态信息,比如文件的偏移量。所有在内存中需要有这个对象记录这些信息。

这个对象是以struct file **fd;形式存储的,如下图所示,一个fd指向一个File Object。

 

image

当然File Object又应该指向其对应的i-node,虽然事实上File Object并没有存inode的指针,而是存着dentry的指针(dentry指向i-node)。这里就引出了下一个概念:目录项(dentry)

目录项与目录项缓存

我们既然有了i-node来表示目录,那为什么还需要dentry呢?原因是VFS经常需要执行目录相关的操作,比如路径名查找等。路径名查找需要不断的解析路径,为了方便起见,就引入了dentry这个概念。目录项没有对应的磁盘数据结构,VFS根据字符串形式的路径名现场创建它。

dentry就是目录的内存表示,比如/tmp/test这个路径,内核为根目录"/”创建一个目录项对象,为tmp创建一个第二级目录项对象,为test创建第三级目录项对象。这里要说明的是/tmp/test和/home/test中test目录项有什么不同,虽然名字同是test,不过很显然它们指的是不同的文件,所以它们的i-node不同。另外,在dentry中会记录其父目录的目录项对象d_parent。当然,如果/home/test是链接到/tmp/test文件上,它们就会有相同的i-node,不过它们的父目录的目录项不同,一个是tmp,而另一个是home。可见,对目录项的hash就应该是针对当前文件名和父目录的目录项对象。

现在我们来说一下目录项高速缓存:

1. 所有未使用的目录项对象都存放在一个LRU的双向链表中,既然是LRU,那当目录项高速缓存空间减少的时候会从LRU的尾部删除。这个链表头存放在dentry_unsued变量中,链表由每个dentry的d_lru变量链接。

2. 在使用的目录项对象是被相应的i-node节点的i_dentry变量所指向,i_dentry同样是一个list头指针,这里用list的原因是每个i-node节点可能与若干硬连接关联。而目录项对象的d_alias变量存放这个链接表的相邻元素。当在使用的目录项对象被删除时就会被移动到上面所说的未使用目录项的LRU中。

3. 散列表dentry_hashtable是一个链表的数组,其作用是用来快速定位dentry的,其hash函数是由目录项的parent指针和文件名决定的。

这里顺便提一下,dentry对象是存储在kernel的slab分配器高速缓存中的,是在Dcahce.c中的dentry_cache。slab高速缓存是内存对象管理的一种算法,这个已经超出了本文的范围。

Mount Point

//TODO:

 

路径名查找

//TODO:

image

 

转自:http://www.cnblogs.com/xuczhang/archive/2010/06/11/1756101.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux VFS(Virtual File System)是Linux操作系统的一个重要组件,用于处理文件系统的访问操作。VFS提供了一个抽象层,使用户和应用程序可以以一致的方式访问不同类型的文件系统,如ext4、NTFS等。VFS的开发是为了增强Linux系统的可移植性和灵活性,使其能够在不同的文件系统上运行,并提供统一的API接口。 在Linux VFS的开发,主要涉及如下几个方面: 1. 文件系统注册和管理VFS通过注册文件系统的方式,将具体的文件系统和VFS绑定起来。开发者需要实现相应的文件系统操作函数,并注册到VFS,以便VFS调用。同时,VFS还负责管理已注册的文件系统,并按照一定的规则进行调度和访问。 2. VFS数据结构设计:VFS涉及到的数据结构设计非常重要,需要考虑到不同文件系统的特点和实现要求。常见的数据结构有inode、dentry、super_block等,它们之间的关系和作用需要合理设计和管理,以保证文件系统的正常运行。 3. 文件系统操作函数的实现:开发者需要根据具体的文件系统类型和需求,实现一系列文件系统操作函数,包括文件的创建、删除、读写等。这些函数需要按照VFS定义的接口规范来进行实现,以保证跨文件系统的通用性和可移植性。 4. 错误处理和异常情况处理:在VFS开发,需要考虑到各种可能的错误和异常情况,如磁盘空间不足、文件不存在等。开发者需要合理处理这些异常情况,给用户提供友好的错误提示和处理方式,以保证系统的稳定性和可靠性。 总之,Linux VFS的开发是一个复杂而庞大的工作,需要对文件系统的原理和实现有深入的了解,同时具备良好的编程技巧和设计能力。通过开发和完善VFS,可以增强Linux系统的文件系统支持和扩展性,提高系统的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值