【linux】基础IO(四)

在上一篇基础IO中我们主要讲述了文件再磁盘中的存储,当然我们说的也都只是预备知识,为这一篇的文件系统进行铺垫。

搭文件系统的架子:

在这里插入图片描述
我们在开始之前还要有一个补充细节:
我们说过文件 = 内容 + 属性
而他们本质上都是数据。

那么内容的数据与属性的数据是在一起存放嘛?
不同的文件系统有不同的规则,在linux下是分开存放

现在我们只要知道每个组内有什么即可。


那我们就先来看存放内容数据的地方:

  • 数据区(Data blocks):存放文件内容

我们在图中展示的的比例大小只是为了好形象的写出各个区域,但实际上数据区占据了90以上的大小
在这里插入图片描述


  • 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用

比特位的位置表示当前块号,1与0代表当前是否被占用。


我们说过内容与属性是分开存放的,那么属性存放在哪里?

  • i节点表(inode Table):存放文件属性 如 文件大小,所有者,最近修改时间等
struct inode
{
	size_t size;
	mode_t mode;
	int creater;
	...
	int inode_number;
	...
	int datablocks[N];
}

注意:
此结构体大小为128字节

同时我们要说明一点,inode内部没有文件名,那么我们怎样标识一个文件呢?使用inode_number进行标识。

也就是下图中的最左方数字
在这里插入图片描述

那么文件的内容与属性如何连接起来呢?
使用datablock这个数组进行连接。
数组中的数字是data blocks的位置。


既然datablock有bitmap,inode也肯定要有一个bitmap用来管理inode。

  • inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。

  • Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。

这个block group里存着这个组的相关管理数据,例如还有多少空的data block ,有多少空的inode_number,组的起始块,结束块位置…


超级块与block group的作用是类似的

  • 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了

但并不是每个组都有一个SB,而是每隔几个就会有一个SB,这样既可以防止磁盘刮花,也不必占用太多的空间存储。


以上也就是我们磁盘级的文件系统!

我们的格式化也就是在每一个分区内分组,再写入文件系统的过程

填补细节:

inode:

我们说过,inode_number是标识磁盘文件的标识符,但有个前提,是在当前分区是唯一的,也就是说,我们inode编号是以分区为单位的!在不同分区内可能会出现相同的inode编号。

在组内进行更详细的划分:在这里插入图片描述
比如我们现在在当前分区有一个inode为10010的编号,怎么找到对应的属性与数据?
我们使用inode编号与[0, 10000], [10001. 20000]…进行对比,发现是在1号(从0号位下标开始)分组内。于是我们便使用10010 - 10001 = 9,使用9在inode bitmap中寻找,观察此inode编号是否合法,合法后在inode table中
找到该属性,最后再通过datablock[]进而找到内容的存放位置。
在这里插入图片描述

datablock[]:

我们在前边说过,inode结构体大小为128字节,那么datablock能占多少呢?
一般我们使用ext2这个文件系统进行讲解,linux也有ext3,4等,在2中有15个元素,那么一个文件只能存60KB
前12个元素确实如此,但是第13,14个元素并不是单纯的映射,15个更是重量级。
在这里插入图片描述
图只是形象,实际肯定更复杂

我们现在只是想输出一个结论:
我们是有能力存大文件的!甚至跨组,但是不建议,因为这样磁头与盘片又会旋转重新寻址,造成效率低下!

更上层的理解:

问题来了,我们在上层使用的都是文件名啊,可是系统都是用inode编号进行标识,那么怎么进行联系呢?

那我们就不得不谈一谈目录了,目录也是文件。

目录 = 内容 + 属性
属性 :不管是什么文件,可执行,目录还是普通文件都是一样的结构体,只是内容不同在这里插入图片描述
那目录的内容里是什么呢?
是文件名与inode编号的映射关系,所以我们在上层不用inode编号,使用文件名即可对文件进行各种操作。

结论:

  1. 所以同一目录下不能存在相同文件名。
  2. 查找文件的顺序,先使用文件名找到inode编号。
  3. 目录权限:

我们回想一下目录权限:在这里插入图片描述

  • x代表当前目录是否可进入当前目录,我们对于x只是简单做一个复习
  • w代表是否可以向目录中创建文件(本质是是否允许我们在目录中建立新的文件名与inode编号映射关系)
  • r代表是否可以在目录中读取文件(本质是是否允许我们向目录中读取文件名与inode编号映射关系)
  1. 如何理解一个文件的增删查改?

增:
对于属性:要申请一个inode编号,先确定在那个分组,然后再在比bitmap中找为0的位置,加上偏移量最终得到inode编号,然后根据inode编号去inode table中申请一个属性结构体,再填上对应的属性。
对于内容,去bitblock中申请位图,看看需要几个,然后在对应的datablock中填上相应的内容,最后建立属性与内容的映射关系,返回inode编号。再在目录内容中建立文件名与inode编号的映射关系
删:
将对应的位图由1直接写为0即可!
这也就是我们为什么下载这么慢,因为要写入数据,而删除改对应的位图即可!
查与改只要有inode编号想怎么查怎么改就怎么做

另外,windows所谓的回收站其实并不是真正的回收站,只是一个目录!如果我们要想在linux中设计一个回收站将rmalias为mv即可。

细节:

细节1:

找到指定的文件->找到该文件的目录->打开目录->找到inode与文件名映射关系->找到inode进而找到属性与内容。

可是我们在这一串关系中仔细一些会发现一个奇怪的现象,找到该文件的目录,我们如果需要实现这一条件也需要找到目录的目录呀
在这里插入图片描述
根目录是系统规定出来的,在我们OS开机时就要知道根目录在哪里,所以我们要找到一个文件需要逆向的文件路径解析---OS自己做的

所以,为什么我们在定位一个文件,无论在什么时候,都需要路径的原因!

可是有人会说我们在执行ls这样的命令就没有带路径啊
在这里插入图片描述
这是因为我们的ls是个进程,进程有自己的cwd(当前路径)
所以我们在ls时本质是这样的!在这里插入图片描述
那么这样次次会不会太麻烦呢?
不用担心,我们的系统会缓存常用路径结构。

如果路径太多了是不是也需要管理呢?
那是不是就需要先描述再组织?

所以我们文件还有一个内核结构体struct dentry用来描述文件路径。
所以我们的struct除了有指向方法表与缓冲区,现在又多了一个指向路径解析的结构体,这个结构体是内核层面,而不是磁盘级层面的。

细节2:

我们在对以上进行分析的时候,都是以某一个确定的分区为前提,可是inode编号在不同分区内可能会一样啊,我们怎么确定自己是在那个分区呢?
在我当前linux环境下,每个人都可能不一样在这里插入图片描述
只有一个盘vda,一个分区vda1
在这里插入图片描述
我们进行上图操作会发现我们的分区是挂载到/目录下的,即当我们在根目录下进行操作时就已经代表我们在那个确定的分区了!

所以目录除了可以定位文件,还可以帮助我们进行确定的分区!

那么目录通常是谁提供的呢?答案是你或你的进程早就已经提供了,就像我们使用exec*系列函数,有选择带路径的或不带的,而使用不带的原因是因为进程已经给我们提供了(环境变量…)
本质是内核文件系统提前写入并组织好我们提供的。

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值