目录
1.认识磁盘、
1.1 理论
1.2 磁盘的物理结构
CHS 寻址
1.3 磁盘的逻辑抽象结构
2. inode 结构
1.Boot Block 启动块
2.Super Block(超级块)
3.Group Descriptor Block(块组描述符)
4.Data Blocks (数据块)
5.Inode Table (inode表)
stat
示例
6.Bitmap 位图
思考:
3.文件系统
3.1 增/删/查/改 一个文件
3.2 理解目录
dentry 缓存:
Preface:
文件系统是一种用于在存储设备上组织数据的方法。Ext2是Linux操作系统中使用的一种文件系统,全称是Second Extended File System(第二扩展文件系统)
尽管Ext2在许多现代Linux系统中已被更新版本的文件系统(如Ext3和Ext4)所取代,它仍然在某些场景下被使用,尤其是在需要快速读写性能且不介意缺少日志功能的场合。
由于Ext2不支持日志功能,因此在系统崩溃时可能会丢失数据或在恢复时需要更长时间。现在,Ext4文件系统已经成为大多数Linux发行版的默认文件系统,因为它提供了更好的性能和更多的功能。
前面我们学习到了一个被打开的文件,那如果一个文件没有被打开呢??
我们可以知道它将在磁盘中进行存储,可以通过如下角度进行思考:
- 路径问题
- 存储问题
- 获取的问题(属性+文件内容)
- 效率
引出了我们的学习路线:
- 认识硬件--磁盘
- 对硬件进行抽象理解
- 文件系统
1.认识磁盘
1.1 理论
磁盘上存储文件属性+内容
- 文件的内容--数据块
- 文件属性--inode
sum: Linux 文件在磁盘中存储,是将属性和内容分开存的
当下磁盘存储的运用场景
1.现在电脑上装的都是SSD了
- SSD代表固态硬盘(Solid State Drive),是一种使用闪存芯片作为存储介质的电脑存储设备。目前个人电脑或工作站等设备普遍采用SSD作为主要的存储介质。SSD相比传统的机械硬盘(HDD,Hard Disk Drive)有更快的读写速度、更低的功耗和更小的噪音,同时因为没有机械运动部件,所 以更耐震动,故障率也相对较低。
2.公司服务器长时间存储还是使用磁盘,进行存储分级:冷热分离
- 在公司或企业的服务器存储解决方案中,尽管SSD在性能上有明显优势,但出于成本和容量考虑,长时间存储大量数据通常还是使用机械硬盘(HDD)。HDD的成本较低,存储容量较大,适合用来存储那些不经常访问但需要长期保存的数据。
- 存储分级:这是指根据数据的访问频率和重要性将存储分为不同的级别。通常分为热存储(hot storage)和冷存储(cold storage)。
- 热存储:用于存储经常访问的数据,这些数据需要快速访问,因此通常使用SSD或快速的磁盘阵列。
- 冷存储:用于存储不经常访问的数据,这些数据可以存储在成本更低的存储介质上,如大容量HDD或更便宜的云存储服务。
意义:优化了成本和性能,确保经常访问的数据能够快速访问,而不常用的数据则以较低的成本进行存储
机械硬盘在计算机系统中的两个特点:它是一种包含机械运动部件的设备,同时也是连接到计算机主机的外部硬件设备
- 磁盘是一个机械设备:
-
- 这里的“磁盘”通常指的是机械硬盘(HDD,Hard Disk Drive),它是由多个机械部件组成的存储设备。在个人电脑或服务器中,尽管还有其他可能包含机械部件的设备(如光盘驱动器、软盘驱动器等),但在现代计算机系统中,机械硬盘往往是唯一的主要机械存储设备。这是因为其他类型的存储设备,如固态硬盘(SSD)、内存条(RAM)、U盘等,都不包含机械运动部件。
- 也是一个外设:
-
- “外设”是外部设备的简称,指的是连接到计算机主机的硬件设备,用于扩展计算机的功能。磁盘(如HDD)作为存储设备,通常被视为计算机的外设,因为它位于计算机主机的机箱外部(或者至少是可分离的),并通过数据传输接口(如SATA、SAS等)与主板连接。尽管它是计算机运行所必需的组成部分,但它并不直接集成在主板上,因此被分类为外设。
1.2 磁盘的物理结构
可以先根据下面的图片,有一个直观的感受
最后一张图的磁盘,类似于三张两面都光的光盘
磁盘作为计算机中唯一的机械部件,通常由一个或多个旋转的盘片组成,每个盘片有两个面,每个面上有一层磁性材料。通过主轴连接,磁盘上附有磁头。数据存储的基本单位是扇区(Sector),传统上每个扇区大小为512字节,但近年来逐渐过渡到4096字节的大扇区。
主轴下面有马达,一秒钟两万转都有可能
物理结构:
- 磁头是一面一个,左右摆动,两个整体移动的,有磁头停靠点
- 磁头和盘面不接触,所以物理上不适用于笔记本,开机状态移来移去,磁头刮花了磁盘,属于硬件问题
- 机械磁盘要在无尘环境下,灰尘落上去就像一座大山,可能会把数据都磨没了
磁盘存储:
- 所有的数据都在盘片上以二进制存储,磁头通过充放电写入
- 内存掉电易失设备,磁盘永久性存储介质
- 通过充放电/强弱/波,在磁盘上写入 01 数据,像吸铁石的 N S 级
- 高温消磁
- 大型互联网公司淘汰磁盘,国家规定不能数据泄露,磁盘擦除并不完全,局部数据的残留也可以被恢复,磁盘上的影子数据也挺危险的,解决方法:和厂商协商,调用接口去除~
磁盘的存储构成
- 磁盘被访问的最基本单元是扇区---大小有可能 512 字节/ 4KB
- 我们可以把磁盘看作由无数个扇区构成的存储介质
3. 第一步:定位一个扇区:哪一面(哪个磁头),哪一个磁道(纵向上形成柱面),哪一个扇区
4. 磁头摆动:定位磁道和柱面的过程
盘片转动:定位扇区的过程
5. 软件寻址,相关内容还是尽量放在一起,因为运动越少,效率越高
CHS 寻址
三个参数:Cylinder(柱面)Header(磁头)Sector(扇区)==》CHS 寻址方式
1.3 磁盘的逻辑抽象结构
我们可以类比于磁带,将扇区线性来看
将一个圆延展开来进行扇形分区(struct 来实现):存储 LBA 信息
随着技术发展,出现了逻辑块地址(LBA)的概念,它可以解决CHS寻址的局限性。LBA将磁盘上的所有扇区视为一个线性序列,操作系统可以通过LBA直接定位到扇区,而无需关心具体的磁头、柱面和扇区信息。
可以借助上图了解,基于对磁盘的理解建模的过程
磁盘对扇区一视同仁的划分,管理好了 10 G 的一个扇形,就能管理好 800 G--分治的思想 化大为小
2. inode 结构
1.Boot Block 启动块
文件系统不仅需要存储文件内容,还需要存储文件的元数据,如文件大小、所有者、权限等。这些元数据存储在索引节点(inode)中。
结合上部分,先来看一下这个 10G 的分区
在Linux文件系统中,Boot Block(启动块)是一个非常重要的组成部分,尤其是在传统的磁盘驱动器中。Boot Block位于磁盘的最前端,通常是磁盘的第一个扇区,也被称作主引导记录(Master Boot Record, MBR)。
Boot Block的功能
- 引导加载:当计算机启动时,BIOS会读取磁盘的第一个扇区(即Boot Block),并将控制权传递给该扇区中的主引导程序。
- 分区检测:主引导程序会检查分区表,确定启动分区的位置。
- 操作系统加载:主引导程序会根据分区表中的信息选择一个活动分区,并加载该分区上的引导加载程序(如GRUB或LILO)。
Boot Block的示例
- 对于一个传统的MBR分区布局,Boot Block(即MBR)的结构如下:
- 主引导程序:占据MBR的前446字节。
- 分区表:接下来的64字节(每个分区条目16字节,共4个)。
- 引导签名:最后两个字节
0xAA55
。对于现代系统的变化
对于使用GUID分区表(GPT)的现代系统,Boot Block的概念略有不同。在GPT分区方案中,磁盘的第一个扇区(通常称为保护MBR)通常包含一个简单的MBR,用于兼容旧版BIOS系统。真正的引导加载程序和GPT分区表位于磁盘的其他位置。
如何查看Boot Block
尽管查看Boot Block的内容通常不是日常管理任务的一部分,但如果需要,可以使用特定的工具来进行。例如,使用dd
命令可以从磁盘复制第一个扇区:
sudo dd if=/dev/sda of=mbr bs=512 count=1
这将把磁盘/dev/sda
的第一个扇区(即Boot Block)复制到文件mbr
中。随后,可以使用十六进制编辑器或特定的工具来查看该扇区的内容。
总结
Boot Block是磁盘上非常重要的一个区域,它包含了启动系统所需的关键信息。无论是传统的MBR还是现代的GPT,Boot Block都扮演着启动过程中的关键角色。
2.Super Block(超级块)
超级块是文件系统中的一种特殊的数据结构,它包含了整个文件系统的全局信息。这些信息包括但不限于:
- 文件系统类型(如ext2、ext3、ext4等)。
- 文件系统块大小(例如1024字节、2048字节或4096字节)。
- 文件系统的总块数和可用块数。
- 文件系统的总inode数和可用inode数。
- 文件系统的挂载时间、上次写入时间、上次检查时间等。
- 文件系统的特征标志(例如是否有日志功能等)。
超级块对于文件系统的正确操作至关重要。如果超级块损坏,可能导致文件系统无法被识别或挂载。大多数文件系统都会在不同的位置保存多个超级块副本,以防止单点故障。
3.Group Descriptor Block(块组描述符)
在某些文件系统中,如ext2、ext3和ext4,文件系统被分割成多个块组,以提高性能和简化管理。每个块组都包含一个块组描述符,该描述符包含了该块组的一些重要信息,例如:
- 该块组内的数据块总数。
- 该块组内的可用数据块数量。
- 该块组内的inode总数。
- 该块组内的可用inode数量。
- 该块组的块位图和inode位图的位置。
- 该块组的inode表的位置。
块组描述符使得文件系统能够快速访问每个块组的状态信息,而无需每次都访问超级块。这对于大型文件系统尤其有用,因为它减少了对超级块的访问频率,提高了性能。
总结一下:
- Super Block:包含整个文件系统的全局信息,如总块数、总inode数等。
- Group Descriptor Block:针对文件系统中的每个块组,包含该块组内的数据块和inode的数量和位置等信息。
这些信息对于文件系统的管理和维护至关重要,确保了文件系统能够正确地处理文件和目录的存储、检索和删除等操作。
4.Data Blocks (数据块)
数据块是文件系统中用于存储文件实际内容的基本单位。每个文件的内容都分布在磁盘上的一个或多个数据块中。数据块的大小取决于文件系统的配置,通常为1024字节、2048字节或4096字节等。
特点
- 可变大小:数据块的大小在文件系统创建时被定义,并且在整个文件系统的生命周期中保持不变。
- 非连续存储:文件的内容不一定存储在连续的数据块中,而是可以分散在磁盘的不同位置。
- 间接寻址:文件的内容通过inode中的指针来间接寻址,这些指针指向文件的数据块。
用途
- 存储文件内容:每个文件的实际内容(如文本、图像、音频等)都存储在数据块中。
- 高效利用磁盘空间:通过允许文件内容分散存储,文件系统可以更高效地利用磁盘空间。
5.Inode Table (inode表)
inode是文件系统中的一个数据结构,用于存储文件的元数据。每个文件都有一个与之对应的inode。inode表则是inode的集合,它包含了文件系统中所有inode的列表。
特点
- 固定大小:每个inode的大小通常是固定的,通常是128字节或256字节。
- 元数据存储:inode中存储了文件的元数据,包括文件的大小、创建时间、修改时间、权限、所有者等。
- 文件内容的指针:inode中包含指向文件数据块的指针,这些指针告诉系统文件内容存储在哪里。
用途
- 存储文件元数据:inode存储了文件的重要属性,如权限、所有者、大小等。
- 文件内容的间接寻址:inode通过指针间接指向文件的内容,这意味着文件名和文件内容是分离的。
- inode与文件名的关联:文件名不在inode中存储,而是存储在目录项中。目录项将文件名与inode编号关联起来,以便通过文件名找到对应的inode。
stat
用法查看文件具体信息
stat [OPTION]... FILE...
- FILE:可以是一个文件名或目录名。
- OPTION:可以是多个选项,用于定制输出信息。
选项
-c
或--format
:指定输出格式,可以使用特定的格式化字符串来自定义输出结果。-f
或--file-system
:显示文件所在文件系统的统计信息,而不是文件本身的统计信息。-L
:递归地显示符号链接的目标的统计信息。-l
:显示符号链接本身的统计信息,而不是链接的目标。-t
或--time=WORD
:指定输出的时间戳类型,WORD
可以是atime
、mtime
或ctime
。-h
或--human-readable
:以人类易读的格式显示文件大小(例如,1K 234M 2G 等)。
使用场景
- 文件调试:当需要了解文件的具体信息时,比如权限、所有者等。
- 脚本编写:在编写 shell 脚本时,可以利用
stat
获取文件的详细信息,进行条件判断或动态生成文件列表。 - 系统监控:监控文件的访问、修改或状态改变时间,用于安全审计或性能分析。
stat
命令是 Linux 系统管理员和开发者不可或缺的工具之一,它提供了文件系统的深入视图,有助于更好地理解和管理文件和文件系统。
会显示 acm(时间戳)
下面解释一下文件的三个时间:
- Access 最后访问时间
- Modify 文件内容最后修改时间
- Change 属性最后修改时间
示例
实现操作的融会贯通:
1. 查看文件example.txt
的inode信息
stat example.txt
这个命令将显示文件example.txt
的inode信息,包括inode编号、文件大小、权限等。
2. 查找文件example.txt
的inode编号
回顾:ls -l
做的就是读取存储在磁盘上的文件信息,然后把它们显示出来
ls -i example.txt
这个命令将显示文件example.txt
的inode编号。
3. 查看文件example.txt
的内容
cat example.txt
这个命令将输出文件example.txt
的内容到标准输出。
4. 假设需要直接访问数据块200(通常不建议这样做,因为它绕过了文件系统)
首先,需要确定文件系统的设备文件,比如/dev/sda1
。然后使用dd
命令读取数据块。以下是一个示例命令,假设每个数据块大小为4096字节,数据块200的偏移量计算方式为200 * 4096
。
dd if=/dev/sda1 bs=4096 skip=200 count=1 of=data_block_200.bin
这里:
if
指定输入文件(文件系统设备)。bs
设置块大小(这里为4096字节)。skip
指定跳过的块数(这里为200)。count
指定复制的块数(这里为1)。of
指定输出文件(这里将数据块内容输出到data_block_200.bin
)。
5. 假设需要修改文件权限
chmod 644 example.txt
这个命令将设置文件example.txt
的权限,使得所有者有读写权限,组和其他用户只有读权限。
6. 假设需要修改文件所有者
chown user:group example.txt
这个命令将更改文件example.txt
的所有者为user
,所属组为group
。
注意:
- 直接访问数据块的操作通常不应该在正常操作中进行,因为它可能破坏文件系统结构。
- 在执行这些操作之前,请确保备份重要数据,避免数据丢失。
- 这些命令可能需要root权限才能执行。
- 文件系统的具体实现可能会有所不同,上述命令是在一般情况下的示例。
总结
- Data Blocks:存储文件的实际内容。
- Inode Table:存储各种文件各自的 inode 元数据,包括文件内容所在的数据块的指针。
通过这种方式,文件系统可以有效地管理文件的内容和元数据,同时也提供了灵活的方式来处理文件的存储和检索。
6.Bitmap 位图
inode Bitmap (属性)位图:
比特位的内容 inode 是否有效的
Block Bitmap (文件内容)位图
和块号联系起来,申请和释放有关,内容块是否存在
思考:
- 删一个文件的时候,用不用把块内容清空呢? 不用清空原始数据,直接把管理 位图清零 即可
- inode 理论上连续的,但是还存在删除后的加入(搜索到空位就添加)
- inode 和 data block 都有对应的编号,可以找到对应的扇区
- super block 整个文件的基本信息,不是每个块组都存有,零零星星的存在,确立了稳健性
- ❗格式化: 每一个分区在被使用之前,都必须提前先将部分文件系统的属性信息提前设置进对应的分区中,方便我们后续使用这个分区或者分组,所以格式化就是把前四个重新设置,后面两个清空
3.文件系统
3.1 增/删/查/改 一个文件
系统做了些什么?
❗ 思路:
Linux 系统中,一个文件,一个 inode ,每个 inode 都有自己的编号(不能跨分区),文件名不属于 inode 内的文件属性!
通过路径能确定 200G ,存到 10G 的块里面了,找组后,在 inode map 里面找空的块
把文件误删了,是把位图删了,删除=允许被覆盖
✔️ 步骤:
系统会执行一系列底层操作来完成这些任务。下面是每个操作涉及的主要步骤:
新建文件
创建一个新文件,操作系统主要会做如下四个操作:
① 存储属性:内核找到一个空闲的结点 (这里是 263466),内核把文件信息记录到其中。
② 存储数据:该文件需要存储在三个磁盘块,内核找到了三个空闲块,300,500,800。将内核缓冲区的第一块数据复制到 300,下一块复制到 500,最后复制到 800……
③ 记录分配情况:文件内容按顺序 300,500,800 存放,内核在 inode 上的磁盘分布区记录了上述块列表。
④ 添加文件名到目录:新的文件名 abc。Linux 在当前目录中记录该文件,通过内核将入口 (263466, abc) 添加到目录文件,文件名和 inode 之间的对应关系将文件名和文件的内容及属性链接起来。
删除文件
- 查找 inode:通过文件名找到对应的 inode。
- 释放 inode 引用:减少 inode 的链接计数。
- 删除目录项:从父目录中删除指向该 inode 的条目。
- 回收资源:如果 inode 的链接计数降为 0,则回收 inode 和其关联的数据块。
- 更新文件系统元数据:更新文件系统的其他元数据,比如文件系统的块使用情况。
我怎么知道一个文件的 inode 编号?
ls -i 可查看,but 使用者基本不关心 inode ,用的是文件名
3.2 理解目录
目录也是文件,也有自己的 inode ,目录也要有自己的属性
目录有内容吗??要不要有数据块?里面放什么呢?
要,该目录下,文件的文件名 和 对应文件的 inode 的映射关系
❗ 所以我们现在就能解释, 为什么同一个目录下不能有同名文件?
ll 查看时,先找到目录的 inode, 目录内容中存储了文件的 inode,找到对应文件的 inode,就可以访问文件内容啦,例如说删除文件实际上是删除文件名与 inode 的关联,也就是从目录项中移除该文件名。这个操作需要对目录进行写操作,因为目录项(包含文件名)存储在磁盘上,并且需要被修改。但是我们限制了这一操作
目录下,没有 w ,我们无法删除文件,没有 r,我们无法查看文件是为什么?
因为想读取,目录不让读,拿什么查找到 inode,还有没有 x 无法 cd,都是通过对目录中 对文件 inode 的访问设置来管理的
目录是文件,也有 inode 编号,那么是如何管理的呢?
往上会一直访问到根目录,相当于是一个递归的实现
dentry 缓存:
- 目录项对象:dentry代表文件系统中的一个目录项,即一个文件或目录的名称与其inode(索引节点)之间的关联。
- 路径解析:当用户或程序请求访问一个文件或目录时,文件系统需要解析路径名,dentry缓存可以快速地定位到对应的inode,从而避免了每次都从磁盘读取目录信息
有绝对路径的话,不就可以从根目录往下拿到对应的 inode 了,为什么还要递归?
递归是我们从内部讲起的,就说要一路找上去,实际拿着文件路径从左到右解析就行,因为我们的任何一个文件,在进程内部都有路径,按照路径,应用层是知道文件和路径的