minix 文件系统

news/2024/9/19 23:51:50/文章来源:https://www.cnblogs.com/rebrobot/p/18316431

来自:https://in1t.top/2020/05/04/minix-1-0-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/

下一个模块将是 fs(file system) 文件系统模块,在开始阅读源码之前,先对 Linux 0.11 中使用的 Minix 1.0 文件系统有个大致的概念,这对之后的代码阅读会有很大的帮助

文件系统是操作系统的重要组成部分,不论是用户文件还是操作系统产生的临时文件等都会通过文件系统来存储,在使用文件时,又要将文件内容从文件系统中读取到内存。因此文件系统需要使用高速设备来存储程序及数据,os 通常使用能存储大量信息的块设备来作为文件系统的设备

基本概念

minix 文件系统由 6 个部分组成:引导块、超级块、i 节点位图块、逻辑块位图块、i 节点块、数据区。对于一个普通的磁盘块设备来说,这 6 个部分的分布如下(以 360KB 的磁盘为例):

minix 文件系统

图中一个格子表示一个盘块,每个盘块大小 1KB,故一共有 360 个盘块,现对这 6 个部分分开描述

 

引导块

引导块是计算机加电启动时由 ROM BIOS 自动读入的存储执行代码和数据的盘块。但一个系统中并非所有盘设备都用于作为引导设备,对于不用引导的盘片,这一块可以不含代码,但必须留出这一块的空间以保证 minix 文件系统格式的统一。如果内核映像文件放在文件系统中,那么就可以在引导块内存放引导程序,由它来获取、加载文件系统中的内核映像文件

 

超级块

超级块用于存放文件系统的结构信息,这些信息都有:

超级块

其中有个新概念叫逻辑块,其实在 Minix 1.0 中,逻辑块与盘块没有区别,一个逻辑块也是 1KB,但在高版本的文件系统中,一个逻辑块通常表示物理上相邻的 x 个盘块(x 是 2 的幂次)。在超级块中,记录一个逻辑块对应多少盘块的字段是 s_log_zone_size(见上图)。由上图可知,逻辑块位图最多使用 8 块缓冲块(s_zmap[8]),每个缓冲块代表 8192(1K * 8bits)个盘块,因此 Minix 1.0 文件系统最大支持 64MB 的块设备

在 Linux 0.11 中,被加载的文件系统超级块保存在数组 super_block 中(定义在 fs/super.c),该数组有 8 项,表明 Linux 0.11 系统中最多可以同时加载 8 个文件系统。该数组在 mount_root 函数中被初始化,在 read_super 函数中会为新加载的文件系统设置一个超级块项,put_super 函数则负责释放数组中指定的超级块项

 

i 节点块与数据区

i 节点是个结构体,用于存放设备上每个文件和目录名的相关信息,实际上文件系统中不是以直观的 [文件名/目录名] 的形式来组织文件层级关系,每个文件和目录都有自己对应的 i 节点,该结构体保存了文件和目录的一些信息,其中就包含了 [文件内容/目录块] 的索引信息。即文件里的实际内容及一个目录下有哪些文件保存在数据区的盘块里,而 [文件/目录名] 对应的 i 节点中有字段指向数据区中实际存储数据的盘块,从而可以获取到其数据

继续以 360 KB 磁盘为例,该文件系统中有 120 个 i 节点(创建文件系统时自动初始化的),每个 i 节点结构体大小是 32 个字节,所以一共需要 32 * 120 = 3840 个字节的连续空间来存储这 120 个 i 节点,舍入一下就是 4 个盘块。对照第一张图,在数据区前确实有 4 个连续的盘块作为 i 节点块

具体的 i 节点结构如下(i_nlinks 字段后面会讨论):

i节点

其中 i_zone[9] 数组就是用来存放文件所占用的数据区中的逻辑块号。前 7 项是直接块号,即前 7 项中的每一项指向一个数据区中的盘块;第 8 项是一次间接块号,即该项指向数据区中的一个盘块(1KB),而该盘块中的每两个字节(注意 i_zone 定义的类型为 short 数组)又指向一个数据区中的盘块,所以 i_zone 中的第 8 项实际可以获取到数据区中的 512(1024 / 2)个盘块;第 9 项是二次间接块号,与第 8 项稍有不同的是经一次间接后找到的盘块其又指向 512 个盘块,故实际上第 9 项可以获取到 512 * 512 个盘块。所以对于 Minix 1.0 文件系统来说,一个文件最大长度为 (7 + 512 + 512 * 512)* 1KB = 262663KB,示意图如下:

i_zone

i_mode 字段也值得考究,它是一个 16 位的字段,用于保存文件的类型和访问权限属性(如 “ls -l” 命令查看到的 “drw-r–r–”),其每位的含义如下:

i_mode

由此可以得知,其实我们常区分的文件和目录在宏观上并没有多少差别,它们都是文件,只不过是不同类型的文件罢了

 

i 节点位图块与逻辑块位图块

i 节点位图用于说明对应的 i 节点是否被使用,1 个比特位代表一个 i 节点,这也就能解释为什么一个盘块可以表示 8192 个 i 节点的使用情况。逻辑位图块与之相似,每个比特位代表对应数据区中盘块的使用情况。这两个块有个共同点,就是它们的最低比特位(位 0)都闲置不用(置为 1)

对于 360 KB 磁盘中的文件系统来说,120 个 i 节点对应 121 位比特位(包含闲置的最低比特位),故一个 i 节点位图块就能搞定。同时,360 个盘块除开非数据区的盘块外一共有 352 个,对应 353 位比特位(同理),因此一个逻辑块位图块也能搞定

 

文件系统目录项结构

通过上面的描述我们可以得知,要想获取一个文件的内容,比如我想获取 /usr/root/hello.c 的内容,顺序查询 hello.c 对应 i 节点的 i_zone 数组即可。那么问题来了,该文件对应的 i 节点地址又从何知晓呢?

实际上,存在一种数据结构叫做目录项,其定义在 include/linux/fs.h:

C
1
2
3
4
5
6
7
8
9
// Line 36
#define NAME_LEN 14
#define ROOT_INO 1

// Line 157
struct dir_entry {
unsigned short inode;
char name[NAME_LEN];
};

一个目录项包含最大长度为 14 字节的文件名和 i 节点号,故一个目录项长度为 16 字节,一个盘块最多可以存放 64(1024 / 16)个目录项。而且根目录(/)的 i 节点号是确定的,为 1。所以如果我想获取 /usr/root/hello.c 的内容,首先就去到 1 号 i 节点(根目录),该 i 节点的 i_zone[0] 中保存了根目录下所有文件的目录项(如 bin、dev、root 等目录文件的目录项)。通过 usr 这个文件名就可以在目录项中找到其对应的 i 节点号,进而找到 /usr 对应的 i 节点,该 i 节点的 i_zone[0] 中也保存了 /usr 目录下所有文件的目录项,通过文件名 root 找到 /usr/root 对应的 i 节点,以此类推便可找到 /usr/root/hello.c 对应的 i 节点,文件名就是这样一层层地被解析到对应 i 节点的

 

硬链接与符号链接

现在就可以来说说 i 节点中的 i_nlinks 字段了,有多少个文件目录项指向该 i 节点,i_nlinks 的值就是多少,其还有一个名称叫做文件的硬链接数。由于目录项的存在,导致多个不同文件名可以同时表示一个文件(只要最后的 inode 值相同),只有当 i 节点的硬链接数为 0 时内核才会真正从磁盘上删除该文件的数据

想必在平时 “ls -a” 时会发现每个目录下都有两个特殊的目录文件 ‘.’ 和 ‘..’,’.’ 对应的目录项给出当前目录的 i 节点号,’..’ 对应的目录项给出了当前目录的父级目录的 i 节点号。所以对于一个目录(比如 /usr/bin)来说,其硬链接数最少为 2,一个是父级目录 /usr 的目录项中有一项指向 /usr/bin 的 i 节点,另一个则是 /usr/bin 目录下的 ‘.’。如果 /usr/bin 目录下还有子目录,则这些子目录的 ‘..’ 也会指向 /usr/bin 的 i 节点,故一个目录的硬链接数等于 2 + 子目录数

另一个与之对应的名词是符号链接(ln -s),与硬链接不同,符号链接文件的数据块中存放的是作为链接对象的路径名字符串,访问符号链接文件时,内核会读取文件中的路径,然后去访问指定的文件,所以符号链接并不会增加目标文件的硬链接数

硬链接与符号链接有一个很关键的区别,那就是因为目录项中的 i 节点号仅能用于当前文件系统,故硬链接不能跨越文件系统。而符号链接则因其存储的是链接对象的路径名,故其可以不局限在一个文件系统中

 

高速缓冲区

块设备的访问速度与内存的访问速度相差甚远,每次文件系统在访问块设备中数据时缓慢的 I/O 操作会对系统性能产生巨大的影响。为了提高系统性能,内核在内存中开辟了一个高速数据缓冲区,并将其划分为一个个与盘块大小相等的缓冲块来使用和管理,以期减少访问块设备的次数。

高速缓冲中存放着最近被使用过的各个块设备中的数据块,当需要从块设备中读取数据时,缓冲区管理程序会先到高速缓冲里找,如果找到了就直接拿来用,否则发出读块设备命令,将数据读到高速缓冲中。当需要把数据写到块设备中时,系统在高速缓冲中找一块空闲缓冲块对这些要写入的数据进行临时存放,直到进行设备数据同步时(如 sync 命令)才会真正将数据写到块设备中

之前在 main.c 源码阅读的文章中给出的内存分布图:

内存分布图

其中的高速缓冲就是这里提到的高速数据缓冲区

 

参考:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/758817.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

栅格地图

在ROS中,地图是非常基本的元素,特别对于2D激光SLAM而言,栅格地图可以说是必不可少的元素。机器人在需要前往目标点时,需要在栅格地图中找到一条合适的路径从当前点到达目标点,这部分内容在move_base中有了详细的接口,可以直接调用并返回路径。但是作为一名工程师,不仅要…

VA02/VA03增加alv

项目背景:搞备库单(新建一种类型的销售订单),备库单不出货(通过排程明细类别控制,也需要新增),正式销售订单创建时,备库单分配数量给正式SO,SO的排程明细类别也是新增的(不跑MRP), 创建后,如果备库单已有库存,则从备库单直接自动调拨库存到正式SO上,还有其它的一…

Folding Strip

第一次在考场中做出来的E题,rank也是来到了20,纪念一下,一定要相信自己呀 构造方法见官方题解,证明见下: 对于原始串\(s\),如果第一个(从左往右数)相同交界不折,选择折后面的交界,那么根据决策包容性,我们可以折一下第一个相同交界,答案不会更差,如下 如果不折第一…

【matplotlib】生成各种图表

一、场景工作中,可能需要使用脚本分析各种数据,并生成图表二、工具matplotlibhttps://matplotlib.org/stable/install/index.html三、安装python -m pip install -U pip python -m pip install -U matplotlib 四、生成图表 1、折线图import matplotlib.pyplot as plt# 准备数…

浅谈cookie和session

最近写了好多次登录注册的业务接口,那不免会听到session、cookie等概念。那么他们是什么呢?之间的关系?有啥作用呢?我这次终于好好捋清楚他们的关系了,这次做一次学习总结。关于用户信息存储相关的问题 背景 先讨论Session和Cookie,我们先了解其诞生的背景,毕竟需求推动…

施工行业必备:2024年值得选择的项目管理工具

国内外主流的10款施工项目进度管理软件对比:PingCode、Worktile、Contractor Foreman、建设工程项目管理平台(JSGC)、智慧工地综合管理系统、工程项目信息管理系统(GCXX)、Buildertrend、Procore、Autodesk Construction Cloud、Fieldwire、ClickUp、monday.com。在施工行…

spingboot 发布 https

1 进入jdk安装目录,我的是在C:\Program Files\Java\jdk1.8.0_311\bin 菜单栏 输入 cmd回车 2. 使用JDK自带的keytool工具生成ssl证书(这里注意JDK版本,版本向上兼容,高版本生成的密钥,不能用于低版本) keytool -genkey -alias gateway -storetype PKCS12 -keyalg RSA -ke…

thinkPHP/fastAdmin框架使用memcached缓存

1.安装memcached扩展: 2.重启PHP,在thinkPHP或者fastAdmin启用扩展(开放相应端口:例如11211) 在fastAdmin中,则需修改config.php里面的cache配置: 3.实际运行测试: 第一个信息正常显示说明运行成功,第二个显示false,说明缓存删除成功每天进步一点点

线性代数过滤的脏水

线性代数 向量 \(\to\),信息学中用形如 \[\begin{bmatrix}a_1\\a_2\\\vdots\\a_p\end{bmatrix} \]的矩阵来表示指向 \(\left(a_1,a_2,...,a_p\right)\) 的 \(p\) 维向量。 向量求和 直接就 \(\vec{a}+\vec{b}=\vec{c}\) 时满足 :投影 借用8分钟带你彻底弄懂《线性代数》-CSDN博…

谷歌为什么要用AIDL替代HIDL(HAL)?

谷歌为什么要用AIDL替代HIDL(HAL)?背景:官方:https://source.android.com/devices/architecture/aidl/aidl-hals.Google 在Android 11引入了AIDL for HALs,旨在代替HIDL原先的作用。在之后的Android版本推荐使用AIDL 实现Hal层的访问。这样做的原因,应该有以下几点:AIDL比…

Halcon的Blob分析

一、Blob分析流程及常用算子 1.基本步骤 Blob分析的基本步骤,这是一种理想状态,也是最基本的套路,获取图像->分割图像(区分前景像素和背景像素)->特征提取(比如面积、重心、旋转角度等)。 halcon代码实现如下: read_image(Image,‘particle’) threshold(Image, …