Linux文件系统软硬链接

ops/2024/10/21 3:01:27/

目录

一、认识硬件--磁盘--永久性存储介质

1.1磁盘的结构

1.2磁盘的存储构成

1.3磁盘的逻辑结构

二、文件系统

2.1文件系统的引入

2.2理解文件系统

2.3对文件增删查改的再理解

2.4如何理解“目录”

三、软硬链接

3.1软链接

3.2 硬链接

3.3ACM


一、认识硬件--磁盘--永久性存储介质

1.1磁盘的结构

  • 主轴(含马达),磁盘(可能有多个盘片,每个盘片有两个盘面),磁头,磁头臂等; 主轴负责磁盘转动,磁头负责读取数据,磁头臂负责将磁头位置的摆动,当不读取数据时负责将磁头停在磁头停泊区
  • 每个盘面有一个磁头,磁头与盘面不接触
  • 每个盘面主要由:磁道,扇面,扇区组成,一般的磁盘设计是磁头沿着磁道由外圈顺时针一直读取到内圈,将每个同心圆(磁道)切割成一个个小小块,称为扇区,扇区是磁盘最小的访问单元,同心圆的扇区一起组成扇面,而第一个扇面又显得重要些,它记录了整个磁盘的重要信息

  • 把处于同一个主轴的磁道垂直扇面相连,称之为柱面

1.2磁盘的存储构成

  • 磁盘被访问的基本单位是扇区-- 512字节/4kb

  • 磁盘可以看成是由无数个扇区组成的存储介质

  • 要访问一个数据,首先要定位该数据在哪一个扇区:找到盘面(定位用哪一个磁头)----找到磁道和柱面----找到扇区,这种磁盘的寻址方法叫做--cylinder header sector--CHS

  • 通过磁头臂摆动定位磁头的位置来找到在哪一个磁道和柱面,通过盘面的转动来找到在哪一个扇区

1.3磁盘的逻辑结构

  • 为什么要对磁盘进行分区?

  • 磁盘的运动越少效率越高,运动越多效率越低,相关的数据一定要有意识的放在一起,所以为了区分存储内容的不同,以及快速定位寻址文件,就需要对磁盘进行分区

  • 数据的安全性隔离:因为每个分区是独立分开的,所以当需要重现格式化或数据重新填充分区A时,分区B并不会受影响

  • 系统的效率考虑:加快数据寻址的效率,当你只有一块分区时,找数据文件a你得重头找到尾部,但是当你分区了,操作系统会记录文件的绝对路径,你就可以直接从某个分区下去找,大大提升了速度和效率

  • 将磁盘的不同盘面进行分区,再对每个盘面上的不同磁道进行分区,再对磁道上的不同扇区进行分区,那么磁盘就被抽象成了逻辑上的基于扇区的数组线性结构,每一个扇区都有对应的下标,我们可以通过扇区的编号(逻辑地址)通过除和取模运算来定位扇区的物理地址,同样也可以用扇区的物理地址来定位扇区的编号,实现了从LBA(扇区逻辑地址)到物理地址(CHS)的相互转化

  • 不仅CPU有寄存器,其他设备也有寄存器,包括磁盘也有寄存器

  1. 控制寄存器--控制IO的方向

  2. 数据寄存器--数据缓冲寄存器,数据寄存器用于存放操作数

  3. 地址寄存器--用来存放访问数据的LBA地址

  4. 用来记录访问状态的结果

二、文件系统

 2.1文件系统的引入

  • 一个被打开的文件,在内存中有对应的数据结构,以及定位访问方法
  • 一个没有被打开的文件,在磁盘中存储,它如何被找到?
  • 文件分为文件内容和文件属性,在磁盘中文件内容和文件属性是分开存储的
  • 如何在磁盘中找到一个文件,如何获取该文件的信息,如何在磁盘中对该文件进行存储,都跟文件系统有关
  • ls -l 读取存储在磁盘上的文件信息,然后显示出来 ,也可以用stat命令来查看更多信息

2.2理解文件系统

  • 前面我们已经说到,可以将磁盘抽象成一个基于扇区的数组,操作系统如何对磁盘进行管理,就是先描述再组织!就要对磁盘进行分区管理!
  • 假设一个磁盘有800G,我们就可以将这个磁盘抽象成一个数组,并对该数组进行分区,200G或150G等等为一个分区,管理一个磁盘,就可以划分为对每一个分区的管理,管理好一个分区,就可以管理好所有分区,进而就可以管理好整个磁盘
  • 那么如何对一个分区进行管理呢?同样对该分区再进行分区,假设该分区200G,再分区为10G,那么管理好每一个10G的分区,就可以管理好该200G分区
  • 我们将这个再分区的小分区叫作Block Group块组,ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成
  • 在第一个块组前有一个Boot Block,是文件系统中的一个特殊块,位于文件系统的起始位置。它包含了引导加载程序(Boot Loader)所需的信息,用于引导操作系统的启动过程
  • 下面我们来看看每一个Block Group的具体包含:

  1. 磁盘是典型的块设备,硬盘分区被划分为一个个的block--文件系统的块大小 。一个 block 的大小是由格式化的时候确定的,并且不可以更改。例如 mke2fs -b 选项可以设定block 大小为 1024 2048 4096 字节,而上图中启动块( Boot Block )的大小是确定的
  2. 存储文件内容的区域叫作--Date blocks,它是以block的形式呈现的,一般为4KB,一般而言一个block只有存储自己该份文件的内容
  3. inode Table:存放每个文件的inode,inode具有唯一编号,一般而言一个文件只有一个inode,linux系统中,文件属性不包含文件名,而是通过文件inode编号来标识文件。每一个inode是一个struct inode数据结构对象,里面存放着文件的所有属性信息,里面包含inode number,文件权限,所属组,拥有者,文件ACM,文件类型,引用计数,以及一个int类型的blocks数组用来建立inode和Date blocks之间的联系
  4. inode Bitmap:比特位的位置和inode的编号映射起来,比特位的内容用来标识该inode是否空闲可用
  5. Block Bitmap:比特位的位置和块号映射起来,比特位的内容记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  6. Group Descriptor Table:GDT,块组描述符,描述块组属性信息
  7. 超级块(Super Block):存放文件系统本身的结构信息。记录的是整个分区的基本使用情况,主要有:每个块组的bolck 和 inode的总量, 未使用的block和inode的数量,每个块组一个block和inode的大小,每个块组的其实inode编号,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息,Super Block的信息被破坏,可以说整个文件系统结构就被破坏了,一般而言,超级块散落分布在一些块组里,不会每个块组里都存在
  8. inode编号的设置是以分区为单位的,不能跨分区有效,每一个分区再被使用之前,都要提前将部分文件系统的信息加载到相应的分区里,方便我们后续使用这个分区或者该分区里的分组
  9. 引入问题:如何知道这些Date blocks中哪些块被使用,哪些块没有被使用,以及如何找到一个文件所使用的块号?
  • 当我们要对一个文件进行读取的时候,首先根据文件的路径找到对应的分区,再根据文件的inode编号找到他所在的块组,然后根据inode编号在inode Bitmap里的映射关系找到对应的比特位,根据比特位内容判断该inode编号是否有效
  • 如果有效就找到该文件的struct inode,struct inode里有一个int block[NUM](假设NUM=15),该数组里存的是该文件所使用的块号!前12个位置对应的是12个块号的一级索引,块号里面存的都是文件内容;13-14块号位置对应的是两个块号的二级索引,块号里面存的仍然是块号而不是文件内容,再根据块号里面的块号找到块号里面的内容;最后一个位置所对应的可以是块号的三级索引,这样我们就可以通过访问int block数组实现对一个文件内容的读取

2.3对文件增删查改的再理解

  • 新建一个文件,系统要做什么?
  1. 当系统新建一个文件的时候,要先判断该文件是否存在,不存在才创建。创建一个文件的时候,首先要该文件申请一个inode编号,再修改inode编号在inode Bitmap的映射位置的内容,表示该inode编号已被使用,然后再在内存中为该文件申请一个inode struct,创建一个文件,底层发生的事情其实就是在硬盘申请一个inode就可以了。
  2. 当我们要对该文件进行写入的时候,回归inode struct可以发现,此时系统是没有为该文件分配磁盘空间的,需要对文件进行写入的时候,首先就要先在硬盘中申请块空间,并根据块号在Block Bitmap中的映射关系修改块位图信息,然后申请一块和该硬盘块关联的内存块,用户写入的数据就存在该内存块中,系统会定时回写到硬盘中对应的块。
  • 删除一个文件,系统要做什么?
  1. 当系统删除一个文件的时候,也是要先判断该文件是否存在,存在才可以删除。删除一个文件的时候,首先根据文件路径找到对应的分区以及inode编号,接着找到该文件的inode struct,根据inode struct中的block数组找到该文件使用的块号,将所有块号在Block Bitmap中映射位置的内容修改,表示块号未被使用后,最后修改该文件的inode编号在inode Bitmap的映射位置的内容,表示该inode编号未被使用了,这样就表示一个文件被删除了
  2. 删除文件的时候,在磁盘中文件内容和文件属性于并没有被删掉,而是等待被覆盖,这就是为什么删除一个文件快,但是新建一个文件慢的原因 
  • 查找一个文件,系统要做什么?
  1.  当系统查找一个文件的时候,也是要先判断该文件是否存在,存在才可以被找到。查找一个文件的时候,首先根据文件路径找到对应的分区和inode编号,inode编号在inode Bitmap中的映射位置有效表示该文件存在且被找到,无效则表示该文件不存在且找不到
  2. 找到有效的inode编号,进而就可以通过inode编号获得文件内容和文件属性
  • 修改一个文件,系统要做什么?
  1. 当系统修改一个文件的时候,也是要先判断该文件是否存在,存在才可以被修改。当要修改一个文件时,首先根据文件路径找到对应的分区和inode编号,进而通过inode编号找到inode struct,获取该文件的内容和属性就可以对文件进行修改!修改内容,如果要新增,当block不够时可以向系统再申请并将Block Bitmap的映射位置内容修改,如果要删除,直接将要删除的块号所映射的Block Bitmap位置内容修改

2.4如何理解“目录”

  • 目录也是文件,也有自己的inode,也有自己的文件内容和文件属性,进而也就有自己的数据块
  • 目录的数据块中放的是该目录下,文件的文件名和该文件所对应的inode的映射关系--这就是为什么我可们通过文件路径得到该文件的inode编号进而找到该文件
  • 为什么一个目录下不允许有同名文件?当两个不同的文件拥有相同的文件名时,我们在根据文件路径(文件名)查找文件的时候,一个文件名会找到两个不同的inode,那么我们就无法区分哪一个inode使我们所要的那个文件的inode
  • 为什么在目录下,没有W权限,我们无法创建文件?因为没有W权限,就无法向该目录的数据块写入内容,而目录的数据块存的是该目录下文件名和inode的映射关系,无法向数据块写入就无法建立某个文件和inode的映射关系,也就无法创建好一个文件
  • 为什么在目录下,没有R权限,我们无法查看文件?因为没有R权限,就无法读取该目录的内容,进而就无法读取该目录的数据块,无法获得要查看的文件名对应的inode,因为要查看一个文件就必须拿到该文件的inode
  • 为什么在目录下,没有X权限,我们就无法进入目录?因为没有X权限,无法对目录进行任何执行操作,也就无法访问到该目录的任何内容,无法进入目录

三、软硬链接

3.1软链接

  • 软链接是一个独立的文件,具有独立的inode,该文件也有数据块,里面存的是指向该文件的路径
  • 软链接就相当于Windows的快捷方式
  • 软链接是通过名字引用另外一个文件
  • ls -s 源文件名字 软链接文件名字

3.2 硬链接

  • 硬链接不是一个独立的文件,没有独立的inode,在linux中可以让多个文件名对应于同一个 inode,硬链接是通过inode引用另外一个文件
  • 所谓的建立硬链接,本质上就是在特定目录的数据块中新增文件名和指向该文件的inode编号的映射关系
  • 每一个inode里面都有一个引用计数器,用来记录有多少个文件名称指向我(一个文件的硬链接数),我们在删除文件时干了两件事情:1.在目录中将对应的记录删除 2.将硬连接数-1,如果为0,则将对应的磁盘释放
  • 硬链接通常用来进行路径的定位,进行目录间的切换
  • 目录内的.和..都属于当前目录文件和上级目录文件的硬链接
  • 不能对目录进行硬链接,可能会导致在查找一个文件时在目录结构中产生死循环
  • ls 源文件名 硬链接文件名

3.3ACM

  1. Access 最后访问时间
  2. Modify 文件内容最后修改时间
  3. Change 属性最后修改时间

http://www.ppmy.cn/ops/127161.html

相关文章

cmake Qt模板

一、常用模块 1. 构建完成后自动调用windeployqt打包 add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND "${QT_PATH}/bin/windeployqt.exe" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe" )需要将QT_PATH设为Qt的安装目录。还可以用-…

【Golang】踩坑记录:make()创建引用类型,初始值是不是nil!!

文章目录 起因二、得记住的知识点1. make()切片,初始化了吗?2. make()切片不同长度容量,append时的差别3. 切片是指向数组的指针吗?4. 切片扩容时,重新分配内存,原切片的数据怎么办? 三、咳咳&a…

【论文阅读】03-Diffusion Models and Representation Learning: A Survey

Abstract(摘要) 扩散模型是各种视觉任务中流行的生成建模方法,引起了人们的广泛关注它们可以被认为是 自监督学习方法【通过数据本身的结构和特征来训练模型,而不是依赖外部标签】 的一个独特实例,因为它们独立于标签注…

博科测试IPO上市丨为行业提供智能测试综合解决方案

近年来,汽车制造、大型基础设施建设以及新能源开发等领域,对高精度、高效率的测试解决方案需求迫切。为推动行业发展,博科测试通过多年的技术积累以及自主创新,围绕伺服液压测试和汽车测试试验领域,积累了多项核心技术…

spring如何解决bean循环依赖的问题

1、概述 spring中,存在A依赖B,同时B又依赖A的情况,这种情况下,spring如何进行bean初始化呢? Service public class A {Autowiredprivate B b; }Service public class B {Autowiredprivate A a; } 本文来解释这个问题…

vector的模拟实现

1.迭代器失效 在上一篇中因为插入导致的扩容,扩容则pos指向的是之前的空间,导致了野指针的出现,没有扩容,使pos的位置意义改变,由于数据挪动,pos不再指向原来的位置,认为上面俩种迭代器失效。(…

重构复杂简单变量之用子类替换类型码

子类替换类型码 是一种用于将类型码替换为子类。当代码使用类型码(通常是 int、string 或 enum)来表示对象的不同类别,并且这些类别的行为有所不同时,使用子类可以更加清晰地表达这些差异并减少复杂的条件判断。 一、什么时候使用…

音视频入门基础:H.264专题(19)——FFmpeg源码中,获取avcC封装的H.264码流中每个NALU的长度的实现

一、引言 从《音视频入门基础:H.264专题(18)——AVCDecoderConfigurationRecord简介》中可以知道,avcC跟AnnexB不一样,avcC包装的H.264码流中,每个NALU前面没有起始码。avcC通过在每个NALU前加上NALUnitL…