1. 磁盘
基本概念
机械磁盘在现在的计算机中基本是唯一的一个机械设备
速度较内存更慢,容量大价格便宜。
磁盘是永久性存储介质,断电后数据还在。
内存是易失性存储介质,断电后(未写入磁盘的)数据丢失。
物理存储结构
扇区:是磁盘存储数据的基本单位,一个扇区通常为512字节。
那该如何定位一个扇区呢?
先定位磁头,确定磁头要访问哪一个柱面(磁道),定位一个扇区。
CHS地址定位
文件=内容+属性 都是数据,我们能定位一个扇区那能不能定位多个扇区呢?
- 磁头(head)数:每个盘片⼀般有上下两⾯,分别对应1个磁头,共2个磁头
- 磁道(track)数:磁道是从盘片外圈往内圈编号0磁道,1磁道...,靠近主轴的同⼼圆⽤于停靠磁头,不存储数据
- 柱⾯(cylinder)数:磁道构成柱面,数量上等同于磁道个数
- 扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同
- 圆盘(platter)数:就是盘片的数量
- 磁盘容量=磁头数×磁道(柱⾯)数×每道扇区数×每扇区字节数
- 磁头在传动臂的带动下共进退
CHS就是通过柱面、磁头、扇区来唯一确定磁盘上的物理扇区。CHS模式支持的硬盘容量有限。
逻辑结构
我们把扇区看成一条线存储的线性结构
这样每一个扇区就有了一个线性地址(其实就是数组下标),这种地址叫做LBA
磁道:某一盘面的某一个磁道展开,即一维数组
柱面:
整个磁盘所有盘面的同一个磁道,即柱面展开。
柱面上的每一个磁道,扇区个数是一样的,这就相当于二维数组。
那我们整个磁盘就是多个二维的扇区数组表(三维数组)
每个扇区都有一个下标,我们叫做LBA地址,其实就是线性地址。
CHS与LBA的互相转换
CHS转LBA:
- 磁头数*每磁道扇区数=单个柱⾯的扇区总数
- LBA=柱⾯号C*单个柱⾯的扇区总数+磁头号H*每磁道扇区数+扇区号S-1
- 即:LBA=柱⾯号C*(磁头数*每磁道扇区数)+磁头号H*每磁道扇区数+扇区号S-1
- 扇区号通常是从1开始的,而在LBA中,地址是从0开始的
- 柱⾯和磁道都是从0开始编号的
- 总柱⾯,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。
LBA转成CHS:
- 柱⾯号C=LBA//(磁头数*每磁道扇区数)(就是单个柱⾯的扇区总数)
- 磁头号H=(LBA%(磁头数*每磁道扇区数))//每磁道扇区数
- 扇区号S=(LBA%每磁道扇区数)+1
- "//":表示除取整
磁盘使用者根本就不关心CHS地址,而是直接使用LBA地址,磁盘内部自己转换。
所以磁盘就是一个 元素为扇区的一维数组,数组下标就是每一个扇区的LBA地址。OS使用磁盘就可以用一个数字访问磁盘扇区了。
2. 文件系统
块的概念
其实硬盘是典型的"块"设备,操作系统读取硬盘数据的时候,不会一个一个扇区的去读,这样效率太低了。会一次性连续读取多个扇区,即一次性读取一个块(block).
硬盘的每个分区是被划分为一个个的"块"。一个块的大小是由格式化的时候决定的并不能更改,最常见的是4KB,即连续的八个扇区组成一个块。
块是文件存取的最小单位。
上面说磁盘就是一个三维数组,我们把它看待称为一个"一维数组",数组下标就是LBA,每个元素都是扇区。
每个扇区都有LBA,那么8个扇区一个块,每个块的地址我们也能算出来。
知道LBA,块号就=LBA/8
知道块号,LBA=块号*8+n(n为块内的第几个扇区)
分区的概念
以我们的windows电脑来看,可能会有一块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的一种格式化。但是Linux设备都是以文件形式存在的,要怎么分区呢。
可以通过
ll /dev/vad*
指令查看磁盘分区信息
柱面是分区的最小单位,我们可以利用参考柱面号码的方式来进行分区,其本质就是设置每个区的其实柱面和结束柱面号码。此时我们可以将硬盘上的柱面(分区)进行平铺将其想象为一个大平面。
柱面大小一致,扇区个位一致,只要知道每个分区的其实和结束柱面号,知道每一个柱面多少个扇区,那该分区多大,就知道了。
inode的概念
我们一直在说文件=内容+属性,在LInux下,内容和属性是分开的。在Linux中任何正常文件都要有自己的属性集合!
上面说过,文件数据都存储在"块"中,那我们还需要找到一个地方来存储文件的原信息(属性信息),例如文件的创建者,文件的创建日期、文件的大小等等。这种存储文件元信息的区域就叫做inode,中文译名为"索引节点"。
Linux下,保存文件属性的集合叫做inode,一个文件,一个inode,inode内有一个唯一的标识符叫做inode号。
我们可以通过,ls -i 指令来查看当前目录下各个文件的inode编号。
在Linux下文件就是通过inode来进行标识的。
ext2文件系统
我们想在硬盘上存储文件必须先把硬盘格式化为某种格式的文件系统才能存储文件。文件系统的目的就是组织和管理硬盘中的文件。
ext2文件系统将整个分区划分成若干个同样大小的块组(Block Group),只要管理一个分区就能管理所有分区每个分区头部有一个启动块(Boot Block)
启动块的大小是确定的为1KB,用来存储磁盘分区信息和启动信息,任何文件系统都不能修改启动块。启动块之后才是ext2文件系统开始
每个块组内部都由超级块(Super Block)、块组描述符(Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)以及数据表(Data Block)组成
- 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:Data Block和inode的总量、未使用的Data Block和inode的数量、一个Data Blocks和inode的大小、最近一次挂载的时间、等其他文件系统的相关信息。Super Block的信息如果被破坏,可以说整个文件系统的结构就被破坏了
- 块组描述符(Group Descriptor Table):块组描述符,描述该分区中块组的属性信息,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,如这个块组从哪里是inode Table,从哪里开始时Data Block,空闲的inode 和数据块还有多少个等等。块描述符在每个块组的开头都有一份拷贝。
- 块位图(Block Bitmap):记录Data Block中哪个数据块已经被占用了,哪些没被占用
- inode位图(inode Bitmap):inode位图记录每个inode是否空闲可用。
- inode表(inode Table):存放文件属性,即每个文件的inode。
- 数据表(Data Block):存放文件内容
1. 其他组块中可能会存在冗余的Super Block,当某一Super Block被破坏后可以通过其他Super Block进行回复。
2. 磁盘分区并格式化后,inode的数量就确定了。
格式化的本质就是写入文件系统的管理信息。
我们如何知道文件在哪一个分组里呢?如何知道分组中位图的哪个位置?
我们拿着一个文件的inode就可以找到文件的所有内容!
inode和数据块是跨组编号的,inode和数据块不能跨分区。
所以在同一个分区内部,inode编号和块号是唯一的
Linux下如何看待目录??
文件名不会作为属性保存在文件的inode中而是保存在当前文件所属目录的数据内容中。
那为什么我们都是通过文件名找文件而不是inode呢?
路径+文件名
先打开我所在的路径,读取对应目录里的内容数据,得到文件名和inode的映射关系,文件名->inode进行文件的查找。
我们访问任何文件都必须有路径
ls /home/pc/code.c
我的路径由谁提供?--->进程提供文件路径
所以找到任何Linux文件都必须从目录开始,进行路径解析,直到找到对应的文件。
以上面/home/pc/code.c 为例
系统读取根目录的inode找到其数据块中的目录项,查找目录项home获取对应的inode号--->访问home目录的inode,读取其数据块中的目录项,查找目录项code.c,获取对应的inode号--->通过inode号找到文件的元数据(权限、大小、数据块位置等),最终访问文件内容
我们访问任何文件都要从/目录进行路径解析吗?
那这不就是一直在做磁盘IO了吗?这样会不会导致效率低下呢?
OS在进行路径解析的时候会把我们历史访问的所有目录(路径)形成一颗多叉树进行保存(linux系统的树状目录结构)这个树形结构整体构成了Linux的路径缓存结构,打开访问任何文件,都先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加detry结构更新路径
怎么理解创建一个空文件?
1. 遍历inode Bitmap,找到比特位为0的位置,申请一个未被使用的inode。
2. 在inode表中找到对应inode,将文件属性信息填到inode结构中。
3. 将该文件的文件名和inode指针添加到目录文件数据块中。
怎么理解向文件写入信息?
1. 通过文件inode号,找到对于inode结构。
2. 通过inode结构找到存储该文件内容的数据块,并将数据写入数据块。
3. 若不存在数据块或者申请的数据块已经写满了,就要遍历block Bitmap来找到一个空的块号,并在数据区中找到对应的空闲块,再把数据写入到数据块中,最后还需要建立数据块和inode结构的对应关系。
删除文件呢?
1. 将该文件对应的inode在inode Bitmap中设置为无效。
2. 将该文件申请过的Data Block在Block Bitmap中置为无效。
所以我们删除一个软件速度比下载同一个软件速度要快的多,当然也因为文件内容并没被删除,所以我们可以在对应内容被其他文件内容覆盖之前通过一些技术手段复原已删除文件。
3. 软硬链接
软链接
软链接又叫符号链接,软链接文件是一个独立的文件,因为该文件有自己的inode号,但是该文件只包含源文件的路径名,所以软链接文件一般就是对应路径文件的一种快捷访问方式,在windows中桌面上的软件图标就是访问对应程序的快捷方式,本质其实就是一个软链接文件。
Linux中可以通过ln -s 文件名 软链接名 设置软链接
并且是一个单独的文件
还可以通过 unlink 软链接名 取消对应的软链接,并且如果一旦删除软链接所指向的文件,那么该软链接文件就没意义了。
硬链接
建立硬链接后会多一个新的文件名指向目标文件(采用引用计数)!!并且硬链接数++
硬链接本质上不是一个独立的文件!因为其没有独立的inode
本质是一组新的文件名和目标inode number的映射关系
什么作用?
主要用来对文件进行备份。
在Linux中,我们可以通过ln 文件名 硬链接名 建立对应的硬链接。同样可以用 unlink 硬链接名 取消对应硬链接。
可以看到建立硬链接后链接数+1
还有一个问题
为什么目录硬链接数不为1呢?
因为我们当前目录下还存在一个隐藏文件 . 指向我们的当前目录,这个 . 文件就是我们的目录硬链接文件。如下图
而..是指向父目录,所以父目录此时的硬链接数就变为3
这篇就到这里啦(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤