Linux文件系统的理解

文件fd

文件fd是指文件描述符,是文件的唯一标识符,不要与进程唯一标识符PID搞混。

文件 = 文件属性 + 文件内容

  • 文件没有被打开时存储在磁盘当中。
  • 而打开文件的本质就是进程打开文件,同时一个进程可以打开多个文件。

 往往很多情况下,OS(操作系统)内部存在大量的被打开文件,此时OS就需要将其管理起来。谈到管理一个东西就不得不提先组织再描述了

文件的管理

每一个进程都有一个PCB(进程控制块,在linux中的具体表现为task_struct这个结构体),为了能管理好进程打开的文件,每个PCB中都存储了一张文件表的指针,这张表本质上是文件指针数组,其中存储了文件指针指向对应的文件。而其下标就是文件描述符

  • 要注意的是文件描述符0,1,2分别默认对应标准输入,标准输出,以及标准错误,并且这三个文件是默认打开的。后续打开的文件将从3开始逐一分配下去。
  • 原则是优先分配最小且没有被使用的下标,假设打开了三个文件,即刚好使用了5号下标,此时关闭3号文件,下次再打开文件时则分配3号下标

重定向及缓冲区

重定向

test.txt文件中开始时什么都没有,而通过重定向到test.txt文件中后再输出opportunity之后却没有输出到屏幕上,而是输出到了test.txt文件中。

所以重定向到底干了什么? 

重定向本质上是:OS内部修改fd对应的内容指向(修改下标对应的指针)

上面这个例子,echo是默认输出到标准输出中的,也就是屏幕上。重定向后文件描述符1指向的文件变成了test.txt。所以导致最后输出到了test.txt文件中。

缓冲区

首先,缓冲区就是一段内存空间缓冲区存在的意义在于给上层提供高效的IO体验,间接提高整体效率。

为什么能提高IO效率?
磁盘的数据读写效率远不如在内存中进行读写,如果频繁地去磁盘进行读写操作会导致IO效率的低下,现在的策略是,读取到缓冲区中后,然后在缓冲区中写好数据后一次性全部写入磁盘当中,减少了对磁盘的读写,效率就上来了。

读写过程

每个文件都有自己的文件缓冲区,在C语言的struct FILE中定义了他的语言级缓冲区,而在OS的struct file定义了内核级缓冲区。

首先会先从磁盘中读取数据到内核缓冲区,用户则是通过库函数(例如fprintf)将数据写入到语言级缓冲区,再一并刷新到内核级缓冲区,最后再更新至磁盘当中。

 缓冲区刷新策略

  1. 立刻刷新(无缓存)
  2. 行刷新   :  一行刷新一次,符合用户的查看情况
  3. 全缓冲   :  缓冲区写满才刷新,一般用于普通文件

注:当进程退出时,系统会自动刷新缓冲区(此次刷新为强制刷新) 

磁盘存储

磁盘构造与基础概念:

 盘片通过高速旋转以及某个磁头来回摆动来定位一个扇区,通过这样的方法定位一块空间。

CHS定址法:

  1. 找到指定磁头   Header
  2. 找到指定磁道   Cylinder
  3. 找到指定扇区   Sector

(如下图,每一圈同色的是磁道,每个磁道分为8个扇区

那么像这样的硬件资源,操作系统又是怎么去管理的呢?

还是那句话,先描述,再组织

首先,先将其进行逻辑抽象。因为每个盘面(一个盘片有两个盘面)存储的数据量是相同的,所以把磁盘给捋直了,将一个圆形结构转换成线性结构。

因为每个扇区存储数据量也是相同的,所以再将其以扇区划分。这样一来,每个扇区都有一个下标。但是还得将下标index转化成CHS。

为了方便计算,我们假设其一个盘面有1000个扇区,10个磁道(即一个磁道100个扇区)

那么此时,若是有N个盘面,就有N*1000个扇区。

  • 取得下标index后,那么这个扇区就在第   index/1000 = H  个盘面上。
  • 为了确定是第几个磁道,还得取临时值temp   index%1000 = temp 。此时就在第   temp/100 = C   个磁道上。
  • 最后求得在第   temp%100 = S  个扇区上
  • 这样一来就通过下标确定了数据存储在第   H   个盘面,第   C   个磁道,第   S   个扇区

然后,因为OS与磁盘交互时的基本单位为4KB,而4KB恰好是8个连续扇区。所以将8个扇区整合成一个块。而文件 = 很多的块构成

 第一个块的下标为0,0*8=0,这个算出来的0则是第一个块的第一个扇区的下标。同理第二个是块的第一个扇区是8,再往后是16。知道起始下标连续读8个扇区就可以知道一个块的所有扇区的下标,再转化成CHS就可以进行定位。

怎么定位的问题解决了,那么接下来登场的是磁盘级文件系统。

如果一次性管理800G内存的话想想都觉得偷偷,于是就将其分区,分成一个个200G,秉承着能管好一个分区就能管好每一个分区从而管好这800G内存。同理,每个分区又可以分成若干组,管好一组就能管好一组。像这样的策略我们称之为分治。

其中每一组中又有六大属性:

在介绍这六个属性前,得先重新了解一下文件是什么。

  • 文件 = 内容 + 属性(属性本质是也是数据)
  • 所以文件在磁盘存储的本质是文件的内容和文件的属性数据。
  • linux文件系统特定:文件内容  和  文件属性  分开存储。

Data Blocks(数据区)

Data Blocks(数据区)作用:只存储文件内容。占小组绝大多数内存。

  • 如果出现存储5KB这样的情况,就直接分配两个块,只是第二个块只用1KB而已。
  • 加载时同样以块为基础单位去加载。
  • 每个块都有自己的块号,可以根据块号反推在哪一个扇区。

Block Bitmap(块位图) 

Block Bitmap(块位图) 作用:用位图记录Data Blocks中哪个数据块被使用,哪个没有被使用。

假设有10000个数据块,那么只需要一个块就能存储Block Bitmap(一个块4kb=4096字节=32768个bit,也就是说4KB能代表32768个数据块的状态) 

inode Table(i节点表)

inode Table(i节点表)作用:存储文件属性

在Linux中文件属性是一个大小固定的集合体(每个文件都有一个这样的集合体。且大小一般为128字节,所以一个块4096字节就可以存储32个文件属性)

注:inode的集合体中不包含文件名,在内核层面每个文件都要有inode_number去标识。(inode number是按分区分配的,意思就是说同一个分区的inode number是不能重复的)

struct inode
{
    int size;
    int creater;
    int time;
    
    int inode_number;

    //存储块号,标记那些块与当前文件有关
    int datablocks[N;
    //...
}

 使用   ll  -li  就能查看文件的inode number,最前面的一串数字就是inode number。

 inode Bitmap(i节点位图)

 inode Bitmap(i节点位图)作用:每一个bit代表一个inode是否空闲可用(比特位的位置代表第几个inode,0或1表示空闲/占用)

GDT

Group Descriptor Table(块组描述符)作用:描述快组属性信息。

Super Block

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

注:超级块记录的是一个分区的信息,而不是一组。其次,并不是每个组都有超级块,但也不只是一个组有,因为每个超级块存储的数据是一致的。而前者的做法是为了节省空间,后者是为了备份,当出现损坏时还能读取另一个超级块的数据进行恢复。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-25 18:34:09       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-25 18:34:09       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-25 18:34:09       82 阅读
  4. Python语言-面向对象

    2024-05-25 18:34:09       91 阅读

热门阅读

  1. 如何开展自动化测试工作,减少线上bug

    2024-05-25 18:34:09       33 阅读
  2. 【6】PostgreSQL 循环

    2024-05-25 18:34:09       28 阅读
  3. ubuntu 安装 kvm 启动虚拟机

    2024-05-25 18:34:09       31 阅读
  4. leetcode397周赛场

    2024-05-25 18:34:09       32 阅读
  5. mongoDB初体验

    2024-05-25 18:34:09       27 阅读
  6. 一个月速刷leetcodeHOT100 day08 两道DP题 一道子串

    2024-05-25 18:34:09       35 阅读
  7. uniapp Vue2钉钉h5开发pdf无法预览的问题

    2024-05-25 18:34:09       29 阅读