本文转载自:链接: 深入理解文件系统 仅供学习使用 侵删 请大家多多支持原创!!!!
当然存在,在磁盘上
单个文件角度 —— 这个文件在哪里?这个文件多大?这个文件的其他属性是什么?
站在系统角度 ——一共有多少个文件?各自属性在哪里?如何快速找到?还可以存储多少个文件
接下来我们来正式了解一下磁盘吧
内存 - 掉电易失存储介质
磁盘 - 永久性存储介质 还有: SSD(固态 贵!) 、U盘、flash卡、光盘、磁带
磁盘是一个外设 且是我们计算机中唯一的一个机械设备(相对而言很慢)
这个磁盘的盘片就像光盘一样,数据就在盘片上放着,只不过光盘是只读的,磁盘是可读可写的
盘面上要存储数据!(二进制) -> 但计算机只认识二进制 -> 二进制是两态 —> 我们想到磁铁也是两态的
机械硬盘的寻址的工作方式:盘片不断旋转,磁头不断摆动,定位到特定的扇区(面 — 磁道 — 扇区)
通过柱面Cylinder —— 磁头Head —— 扇区Sector 的寻址方法为CHS寻址
扇区的大小:512字节是硬件上的要求(外磁道和内磁道都是一样大小,密度不一样)
类比磁带,我们可以把磁盘盘片想象成线性结构。
站在OS角度,我们就认为磁盘是线性结构,要访问某一扇区,就要定位数组下标LBA(logic block address);要写到物理磁盘上,就要把LBA地址转化成磁盘的三维地址(磁头,磁道,扇区)。这种关系类似于我们之前的虚拟地址空间和物理内存
所以:找到特定扇区的位置 ——> 找到数组特定的位置;对磁盘的管理——> 对数组的管理
文件在磁盘上是如何被保存的?文件是在磁盘中的,而磁盘现在被我们想象成一个线性结构。
1️⃣ 分区:大磁盘 → 小空间,化整为零
2️⃣ 格式化:给每个分区写入文件系统
所以理论上,我能把这100G的小空间管理好,其他空间就复刻我就好啦,因为硬件都是标品,当然了不同分区也可以写入不同的文件系统
boot block 存在于每个分区的开头,备份文件,是与启动相关的,供启动时查找分区
我们再把剩下的空间继续拆解分组,Block group 0 ,Block group 1 … 那么问题就又变成了如果我能管理好Block Group 0,就能管好1~n这些,因此研究文件系统又缩小范围了,就变成研究这一个Block Group 0
话不多说开始吧
虽然磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB(8*512字节),4KB是block大小,所以磁盘被称为块设备
哪怕我们只想在磁盘上读取1字节,OS也必须直接读取4KB的数据
原因有两个:
inode内部保存了一个数组,保存了对应块的编号,二者关系就联系起来了
Linux中真正标识一个文件,是通过文件的inode编号,一个文件,一个inode(属性集合);一个inode也都有自己的编号。
那么要创建文件就要在inode Table中申请一个未被使用的inode,填入属性;文件中还有内容,inode还用数组存储了相关联的blocks块编号,我们可以简单地理解成 ——
struct inode{
//文件的大小
//文件的inode编号
//其他属性
int block[15];
}
⚡万一这个文件特别大呢? 怎么办?
可是我们怎么知道inode呢?(Linux中,inode属性里面,没有文件名这样的说法)
预备知识:
回答上面的问题:我们是依托目录文件来找到inode编号,因为目录的data block中保存了inode编号和文件名的映射关系,所以能找到文件名进而找到inode编号
灵魂多问:
目录下创建文件:遍历inode Bitmap,位图中找0,申请一个未被使用的inode,随后便置1;向inode table中填入属性信息(权限、ACM时间)。并把这个映射关系(文件名是用户输入,inode是我们从文件系统申请得到的)写到当前目录的Data blocks中。
查看文件内容:cat hello.c → 查看当前目录的data Blocks数据块儿 → 找到映射关系:文件名儿对应的inode编号 → 在inode Table中找到inode → 找到对应的blocks[] → 文件内容加在进内存中,在刷新到显示屏。
删除文件 :在目录的data block,用户提供的文件名,以文件名作为key值索引对应的inode,在inode Bitmap中把对应的比特位置中由1置0;再根据属性把使用的数据块儿们也在Bitmap中把它由1置0。最后在目录的data block中,删除inode和文件名的映射关系。
所以拷贝一个文件需要一会儿,但是删除很快(因为不需要改文件的属性inode Table和数据data Blocks,标志文件无效即可,并不用覆盖)
( 如果你在Linux系统中,不小心rm -rf误删了文件,还能恢复!(前提是inode未被使用,inode和data block没有被占用)最好的做法就是什么也不做!找到你在windows下删除文件到回收站,其实只不过是转移了目录,在回收站中删掉才是相当于1置0了)
还有一个问题:位图一开始是不是要被操作系统全清0,那个区域要被分成inode table和super在什么位置 ?GDT是谁写的?inode table的128kb是谁划分的?
以上所有的信息都是:格式化 也就是写入文件系统(写入属性)
【面试题】:
系统里还有空间,为什么创建文件老是失败:
因为inode是固定的,data block也是固定的。可能存在 inode还有,data block不够了;inode没有,data block还有的情况(特别少)
说了一大圈,最终为了引出我们的大boss
建立软链接
ln -s testLink.txt soft.link
删除链接,可以rm,但是更建议
unlink soft.link
什么时候会使用到软连接呢?
对于一些执行路径非常深的程序,我们不用每次都输入长长的路径,我们可以通过软链接快速找到它
现在我不断回退,退到所谓工作目录上来,这时如果我还想运行test.sh就比较麻烦,那么我们就可以通过建立软链接的方式 ——
不带s就是硬链接
ln testLink1.txt hard.link
我们观察发现,软链接是有自己独立inode的,即软链接是一个独立文件!有自己的inode属性集也有自己的数据块儿 (保存的是它所指向文件的路径 + 文件名)
而硬链接自己没有独立的inode,用的是别人的inode;根本就不是一个独立的文件,说白了就起别名,其本质:在特定目录下,添加一个文件名和inode编号的映射关系,仅此而已
我们还发现在属性中有一个数字,1-> 2 ->1,这个数字就叫做硬链接数
当我们删除一个文件的时候,并不是把这个文件inode删除,而是把inode引用计数–,当引用计数为0(没有文件名与之关联)的时候,这个文件才真正删除
为什么创建一个文件的时候,硬链接数是1?
首先目录和自身的inode就是一组映射,第二个是目录内部的. 和inode 也是一组映射
在dir下又创建了d1目录,此处为什么dir的硬链接数变成3了?
因为d1的有…文件指向上级目录dir,所以硬链接数+1