深入linux内核架构 ext2,读书笔记-深入linux内核架构-Chapter8-part1

《第八章》虚拟文件系统

VFS的层次

文件系统实现与用户进程(或C库)之间。

5459ea126109e2ebc25dbf3e112c46aa.png

文件系统分类

基于磁盘的文件系统(ext2/3  fat  iso9660…)、虚拟文件系统(proc)、网络文件系统(nfs)

通用文件模型

VFS提供一种结构模型,包含了一个强大的文件系统所应具备的所有组件。所有的文件系统实现,都必须提供与VFS定义的结构配合的例程,以弥补两种试图之间的差异。

文件描述符

一个整数,在用户层所有有关文件的操作中用于标识一个文件,在打开文件时由内核创建,特定于进程。

inode

linode是什么?

²inode用来存放文件的元数据(例如,文件的创建者、文件的创建日期、文件的大小等等)

²注意inode并不包含文件名。

linode的内容

inode包含文件的元信息,具体来说有以下内容:

²文件的size、文件属主的User ID、Group ID

²文件的读、写、执行权限

²文件的时间戳,:ctime(inode上一次变动的时间)、mtime(文件内容上一次变动的时间)、atime(文件上一次打开的时间)。

²链接数,即有多少文件名指向这个inode。

²文件数据分布在哪些磁盘Block。

linode的状态

每个inode处于三种状态中的一个:

²inode位于内存中,未关联到文件;(inode_unused)

²inode位于内存中,由一个或多个进程使用,已与磁盘同步;(inode_in_used)

²inode处于活动使用状态,与磁盘上内容未同步,脏inode;

linode是如何组织的?

²内核使用两种方式组织inode。

²链表:每个inode都有一个i_list成员,可将inode存储在链表中。(inode出现在特定于超级块的链表中i_sb_list,同时出现在特定于状态的链表中,例如inode_in_used)

²散列:每个inode同时出现在一个散列表中(根据inode号快速访问inode)。

l目录是什么?

²Linux下,目录也是文件,也有inode和数据部分,其数据部分内容如下:

第一部分表示对应inode的编号(系统内唯一),第二部分表示文件或目录的名字。

293dd4d73dfdb15e5ea237800fe1a4a4.png

内核如何访问/user/bin/emacs

首先读取根目录(这个在内核中一直被维护,),在根目录文件的数据部分查找user这个目录项,根据其中的inode编号,获取inode。bin的查找类似,一直到查找到emacs,找到emacs对应的inode,该inode的数据部分即emacs这个文件(普通数据文件)的内容。

图示:

f9f38b625a899003c668738caba0c6a6.png

目录项缓存dentry:

l引入dentry

上述访问/user/bin/emacs过程非常耗时,需要不断地读取inode和对应的数据部分。为了加速,内核将之前访问过的目录或文件(统称为目录项)缓存起来,下次再访问同样的目录项(例如,/user/bin/vi的/user/bin/部分)时,可以直接找到对应的inode(上图中为10号)。

ldentry的目的:

dentry的主要用途是建立文件名和inode之间的关联。

所以该结构体包括两个最主要的字段,d_inode和d_name。

其中,d_name为文件名。qstr是内核对字符串的封装(可以理解为带有散列值的char*)。

d_inode是与该文件名对应的inode。

ldentry结构体:

structdentry {

/* Where the name belongs to - NULL is negative */

structinode *d_inode;

structqstrd_name;

structdentry *d_parent;/* parent directory */

union{

structlist_headd_child;/* child of parent list */

structrcu_headd_rcu;

}d_u;

structlist_headd_subdirs;/* our children */

structdentry_operations *d_op;

structsuper_block *d_sb;/* The root of the dentry tree */

unsignedchard_iname[DNAME_INLINE_LEN_MIN];/* small names */

};

l什么时候创建

在VFS(以及文件系统实现)读取一个目录项(目录或普通文件)后,则创建一个dentry来缓存找到的数据。

l内存中这些dentry如何组织管理

²结构:各个dentry实例组成了一个网络,例如,当前dentry实例对应的所有文件和子目录相关联的dentry都归入到d_subdirs中。

²组织方式一:内核所有活动的dentry实例都保存在一个散列表中,该散列表使用dentry_hashtable实现(全局dentry散列表)。

²组织方式二:LRU链表,长时间不使用的dentry会被删除。

链接link

l两类链接:符号链接(软链接)和硬链接。

l符号链接(软链接)文件使用自己的inode,该inode的数据部分包含了一个字符串,给出了链接目标的路径。

l硬链接创建时,使用了已有的inode编号。硬链接建立以后,无法区分原来的文件和新建的硬链接文件。这种情况下,inode使用计数器来确保文件删除操作中,当没有其他文件使用该inode时,才能真正删除该inode。

示意图:

b9573aceca37ddd206033a61271c92da.png0dc101f8f976847e2be64ec1bce851ee.png

特定于进程的信息

structtask_struct {

...

/*进程的文件系统相关的信息*/

structfs_struct *fs;

/*该进程打开的文件*/

structfiles_struct *files;

...

}

structfiles_struct {

...

structfdtablefdtab;

structfile *fd_array[NR_OPEN_DEFAULT];

};

structfile {

...

structpath *f_path;

loff_t   f_pos;

...

};

structfile_operations {

...

ssize_t (*write) (structfile *,constchar__user *, size_t, loff_t *);

int(*readdir) (structfile *,void*, filldir_t);

unsignedint(*poll) (structfile *,structpoll_table_struct *);

int(*ioctl) (structinode *,structfile *,unsignedint,unsignedlong);

int(*mmap) (structfile *,structvm_area_struct *);

int(*open) (structinode *,structfile *);

...

};

structfile_operations->open函数实质上是将一个file对象关联到一个inode。

poll函数也在其中。

从task到dentry/inode

b5cb3261980877097f151ffacbdd175d.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值