Linux 文件系统(二)---执行过程及结构间的关系
一、首先,看看磁盘,超级块,inode节点在物理上整体的分布情况:
(图示来自:www.daoluan.net)
对于一个分区,对应一个文件系统,一个文件系统其实本质上还是磁盘的一部分,所以可以包括多个柱面。对于柱面上的数据,主要看看inode节点位图、block位图,i节点,数据块。inode节点位图是为了记录inode节点的使用情况,之前的违章中已经说过,inode节点在文件系统安装的时候,会初始化所有的inode节点,那么形成的位图表示使用or没使用的大表。对于block块也是一样的,记录数据块使用情况。
对于inode节点来说,每个文件都会对应一个inode节点,目录项也会对应一个inode节点。对于一个文件来说,只对应一个inode节点,但是一个文件可以有多个数据块,因为一个比较大的文件,一个数据块根本存放不了。所以inode中记录多个文件数据块的信息。
对于目录块来说,主要是为了索引而存在,所以里面的内容主要是inode节点号和文件名,其实就是一个映射表形式的东西。
二、
上一篇中对于VFS有一个简单的介绍与理解,我们知道,与用户打交道的是VFS,然后VFS与底层真正的文件系统交流。那我们知道在一个VFS下面,允许存在很多的“文件系统类型”,例如ext2,ext3,ext4,sysfs,proc等等。这些类型是可以共存的,同时,对于每一个类型来说,可以存在多个文件系统实体,例如:在一个目录下有多个子目录,子目录之间的文件系统类型可以不一样,也可以有部分是一样的类型,借用windows中的例子说就是,D盘和E盘可以都是NTFS类型文件系统,也可以是不一样的文件类型系统。
在Linux中,系统有一个全局变量叫做file_systems,这个变量用来管理所有的“文件系统类型”链表。也就是所有的文件系统类型都必须注册到(链接到)这个链表中,才可以被使用。如果是自己的文件系统,只要符合VFS的标准,也是可以注册进去的。最终形成一个单链表形式结构。
而对于一个文件系统类型,使用file_system_type结构表示:
- <span style="font-size:14px;">995 struct file_system_type {
- 996 const char *name;
- 997 int fs_flags;
- 998 struct super_block *(*read_super) (struct super_block *, void *, int);
- 999 struct module *owner;
- 1000 struct file_system_type * next;
- 1001 struct list_head fs_supers;
- 1002 };</span>
字段意思:
name:文件系统类型名称,如ext2。
flags:安装文件类型标志,在fs.h中有定义。
read_super:各种文件系统读入其“超级块”的函数指针,不同的文件系统之间可能不一样,因此读入函数也不一样。
owner:如果这个文件系统是通过一个可安装模块实现的,那么这个指针指向这个模块。
next:这个就是链接到下一个“文件类型”的指针。
fs_supers:属于相同的文件系统类型的所有的super_blocks构成一个双向链表。在超级块中有一个s_instance就是连接这个双链表的连接点。(超级块在上一篇有介绍)
1、
那么根据上面的解释,一个大的框架图如下:
同时,在内核中,有一个全局的变量super_blocks用于将所有的suoer_block连接在一起,形成一个双向链表,这样就会发现s_list字段就有意义了!
如图:
2、我们在之前也提过,文件系统最终还是要和进程一起协作的,任何对于文件的操作都是基于进程的。由操作系统的知识我们知道,对于进程来说,管理进程的叫“进程控制块PCB”,这个在内核中的结构为:task_struct,这个是很复杂的一个结构体,对于进程来说,可以有自己的操作的文件,那么进程的文件的信息,也是包含在这个结构中:
- 283 struct task_struct {
- ... ...
- 391 /* filesystem information */
- 392 struct fs_struct *fs;
- 393 /* open file information */
- 394 struct files_struct *files;
- ... ...
- }
代码中的两个字段就是涉及进程的文件的字段。每个进程在PCB中保存着一份文件描述符表,文件描述符就是这个表的索引(数组的下标),每个表项都有一个指向已打开文件的指针。
代码中第一个字段fs:代码本进程自身的文件系统的信息。例如进程本身的根目录,挂载点,当前目录等信息。
代码中第二个字段files:保存着本进程涉及的所有的文件的信息的指针。files_struct结构之前已经说过:files_struct
里面有两个重要字段:
- 172 struct files_struct {
- ... ...
- 178 struct file ** fd; /* current fd array */
- ... ...
- 183 struct file * fd_array[NR_OPEN_DEFAULT];
- 184 };
fd就是涉及到的所有的文件的数组指针!一般情况下fd就是fd_array,但是如果打开的文件超过NR_OPEN_DEFAULT,那么就会重新分配新的数组,然后fd指向新的数组。
对于一个文件数组来说例如:fd[],所谓“文件描述符”其实就是这个数组的下标!例如:默认0就是标准输入文件描述符,1是标准输出,2是标准错误。对于用户来说操作的是这个“文件描述符”,但是对于内核来说,“文件描述符”仅仅是为了找到对应的文件而已!然后所有的在内核中的操作,都是使用实际文件的file指针进行的!关于file结构体在上一篇也说了(之前files_struct链接)。延伸一下:我们在写C语言程序的时候会遇到两个函数,open和fopen。对于前者,返回的就是一个“文件描述符”,即那个文件数组的下标,对于fopen,返回的是一个FILE的指针,这里面其实除了“文件描述符”之外,还包括IO缓冲这些信息。文件指针FILE*更上层,FILE指针将文件描述符和缓冲区封装在一起。
OK,那么用户进程打开一个文件的具体的过程是什么呢?下面分析总结一下:首先我们知道用户使用open返回一个“文件描述符”(具体怎么获得,之后再说),然后在进程PCB中,即task_struct文件数组中找到对应“文件描述符”(数组下标)的文件(file)指针,在file结构体中,f_dentry记录了这个文件的完整目录项,一般在内存中会有dentry的缓存,通过这个我们可以找到文件的inode。对于一个dentry来说,也是有自己的inode,目录名称之类信息。总之通过dentry,可以找到最终文件的inode,找到inode之后,就可以定位到具体的文件数据在磁盘上的位置了!
对于上面的过程,整体的一张图如下:
3、多个进程和多个文件之间的关系:
对于一个进程来说,可以打开多个文件,也可以多个进程打开一个文件,对于文件来说,不变的永远是自己的inode节点,变化的仅仅是和进程直接关系的file结构。可以看一下下面的大图:
Linux 文件系统(二)---执行过程及结构间的关系相关推荐
- linux每隔多久调度y,Linux 进程调度+Linux系统一般执行过程 笔记
进程的调度时机与进程的切换 操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已. 对于理解操作系统的工作机制,反而是进程的调 ...
- Linux 命令的执行过程/Shell提示符/alias命令
在 Linux 系统中"一切皆文件",Linux 命令也不例外.那么,当编辑完成 Linux 命令并回车后,系统底层是怎么执行的? 1) 内核层 内核层是 UNIX/Linux 系 ...
- linux进程上下文切换的具体过程,Linux实验三 结合中断上下文切换和进程上下文切换分析Linux内核一般执行过程...
fork系统调?创建?进程,也就?个进程变成了两个进程,两个进程执?相同的代码,只是fork系统调?在?进程和?进程中的返回值不同. 打开linux-5.4.34/arch/x86/entry/sys ...
- Linux 系统调用的执行过程
什么是系统调用 系统调用 (在 Linux 中常称为 syscalls ) 是应用程序访问硬件设备之间的桥梁. 系统调用层为用户空间提供一种硬件的抽象接口,使得用户不用关注设备的具体信息,同时系统调用 ...
- 分析teamTNT团队Linux挖矿木马执行过程与防范
分析teamTNT团队Linux挖矿木马执行过程与防范 公司需要扩展海外业务,需要有一台海外云服务器.当我们把应用部署上去时的第二天所有应用down掉了,然后发现ssh连接服务器特别慢.好不容易连接上 ...
- Linux文件系统二(虚拟文件系统VFS实现原理)
创作人QQ:851301776,邮箱:lfr890207@163.com 欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点! 个人座右铭: 1 ...
- linux内核make执行过程
本篇基于上一篇<<linux内核make menuconfig执行过程>>基础上,追溯make执行过程. make 1. 与make menuconfig相同的部分 这部分内容 ...
- linux执行class文件_深入理解linux内核——可执行文件执行过程(2)
接上篇.. 13.调用do_mmap()函数创建一个新线性区来对可执行文件正文段(即代码)进行映射.这个线性区的起始线性地址依赖于可执行文件的格式,因为程序的可执行代码通常是不可重定位的.因此,这个函 ...
- linux 文件可执行_深入理解linux内核——可执行文件执行过程(2)
接上篇.. 13.调用do_mmap()函数创建一个新线性区来对可执行文件正文段(即代码)进行映射.这个线性区的起始线性地址依赖于可执行文件的格式,因为程序的可执行代码通常是不可重定位的.因此,这个函 ...
- linux 跟踪命令执行过程,Linux的strace命令跟踪线程死锁
strace命令,是Linux提供的跟踪系统调用的命令,需要sudo或root权限,可以查看进程(线程)使用的系统调用. 基本用法:sudo strace -p 进程号 如果一个线程递归获取同一个锁, ...
最新文章
- RandomUnderSampler 中的fit_resample 是 imblearn.base.py中调用output = self._fit_resample(X, y)
- 十一、explain属性介绍
- HttpServlet概述及应用
- 模切ERP和免费OA系统是互相结合提高效率
- java去掉mongodb日志_MongoDB日志文件过大的解决方法 清理
- 正则表达式JavaScript版本回顾笔记背诵版本
- 如何修改magento产品详细页面的栏目
- 如何创建一个Mybatis程序,实现对数据库的简单查询?
- Cisco路由配置命令
- java8新特性和汪文君Google Guava项目实战视频
- Python基础 -- 注释、变量以及数据类型、标识符和关键字、类型转、运算符
- Windows下usb接口驱动技术(一)
- PS去水印的四种方式
- linux系统下的微信安装(ubuntu20.04)
- 如何用阿里云云盘快照恢复部分数据
- NFC开发 —————实现NFC手机做门禁卡的方法(二)
- win10激活错误,软件授权服务报告无法激活计算机怎么办?
- 别人花了几万元学的英语,我帮你们免费弄来了
- HTML5作业:美食网站设计(浮动的使用)
- pytorch里面nn.Module讲解