当前位置: 首页 > ops >正文

Linux--存储系统探秘:从块设备到inode

想象一下,当你轻轻敲下ls -l命令时,背后正上演着一场精彩绝伦的"数据寻宝记"💎;当你创建或删除文件时,系统底层正在进行着精密的"数字积木游戏"🎮。这些看似简单的操作背后,隐藏着Linux文件系统精心设计的存储架构。

在这篇博客中,你将了解到:

  • 块(Block):数据存储的基本单位,就像乐高积木一样构建起整个文件世界🧱

  • 分区(Partition):如何将物理磁盘划分为逻辑独立的存储王国🍰

  • inode:文件的"基因密码",记录着所有关键属性信息🧬

  • 目录与文件名:Linux如何巧妙管理(inode, 文件名)的映射关系🗺️

准备好你的"探险装备"🔦,让我们开始这段奇妙的Linux存储系统探索之旅吧!每一段知识都像一颗等待被发现的宝石💎,而你就是那位幸运的寻宝者!

 1.“块”的概念

🔍 块(Block)是什么?

想象一下硬盘就像一座巨大的"数据乐高城"🏙️,而"块"就是构建这座城市的最小积木单位!操作系统可不会一块一块地搬积木(那太慢啦🐢),而是一次性搬一整组积木🚚,这就是"块"的精妙之处!

其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样

效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个”块”(block)。

硬盘的每个分区是被划分为⼀个个的”块”。⼀个”块”的⼤⼩是由格式化的时候确定的,并且不可

以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个 ”块”。”块”是⽂件存取的最⼩单位

[ljh@lijunhua-allcloud stdio]$ stat main.c
File: 'main.c'
Size: 488    Blocks: 8    IO Block: 4096    regular file
Device: fd01h/647694    Inode: 1052007    Links: 1
Access: (0664/-rw-rw-r--)   Uid: (1000/    whb)   Gid: (1000/    whb)
Access: 2024-10-25 22:15:52.909616443 +0800
Modify: 2024-10-17 19:06:11.139423737 +0800
Change: 2024-10-17 19:06:11.139423737 +0800
Birth: -

看这个有趣的stat命令输出🔍:

  • 文件大小只有488字节📏,但却占用了8个Blocks!

  • 每个Block大小是4096字节(4KB)🧩

  • 就像把一个小玩具放进大箱子📦,虽然浪费了点空间,但搬运效率大大提高🚀

🧮 块的寻址魔法 注意:

磁盘就是⼀个三维数组,我们把它看待成为⼀个"⼀维数组",数组下标就是LBA,每个元素都是扇区

每个扇区都有LBA,那么8个扇区⼀个块,每⼀个块的地址我们也能算出来。

块号 = LBA/8

LBA=块号*8 + n. (n是块内第⼏个扇区)

🌟 为什么要有块?

  1. 效率之王👑:一次性读取多个扇区,就像用购物车🛒而不是手提篮买东西

  2. 空间管理大师🧙♂️:即使文件很小,也至少占用一个块,就像最小包装单位

  3. 系统基石🏗️:所有文件操作最终都要落实到块的操作

💡 小贴士:块大小在格式化时就确定了,就像乐高积木的规格,一旦确定就不能轻易改变哦!

2.“分区”的概念

🎂 什么是磁盘分区?

想象你的硬盘是一个超大的生日蛋糕🎂,分区就像把这个蛋糕切成几块:

  • Windows世界:C盘、D盘、E盘...就像把蛋糕切成几块分给不同朋友🍰

  • Linux世界:虽然也是切蛋糕,但我们用更优雅的"文件式"管理方式📁

🔧 分区的本质

分区实际上是对硬盘进行"高级格式化"✨:

  1. 物理层面:在蛋糕上划出分界线

  2. 逻辑层面:为每块蛋糕准备不同的盘子(文件系统)

# 查看磁盘分区情况的魔法命令🔮
sudo fdisk -l
Disk /dev/sda: 500GB
Device     Boot     Start       End   Sectors  Size Id Type
/dev/sda1  *         2048   1026047   1024000  500M 83 Linux
/dev/sda2         1026048 976771071 975745024 465.3G 8e Linux LVM

🧮 柱面:分区的"最小计量单位"

硬盘就像由无数个"柱面甜甜圈"🍩堆叠而成的圆柱体:

  • 柱面编号:每个甜甜圈都有唯一编号

  • 分区规划:只需要记录起始和结束的甜甜圈编号

💡 专业小知识

知道起始柱面号 + 每个柱面的扇区数 = 就能计算出LBA范围!
这就像知道蛋糕切块的起止位置就能算出这块有多大📏

我们可以利⽤参考柱⾯号码的⽅式来进⾏分区,其本质就是设置每个区的起始柱⾯和结束柱⾯号码。 此时我们可以将硬盘上的柱⾯(分区)进⾏平铺,将其想象成⼀个⼤的平⾯,如下图所⽰:

3.“inode”的概念

📌 文件的双重身份:数据+属性

在Linux世界里,每个文件都像一位公民👤,拥有:

  • 身体(文件数据)💾

  • 身份证(文件属性)🆔

之前我们说过 ⽂件=数据+属性 ,我们使⽤ ls -l 的时候看到的除了看到⽂件名,还能看到⽂件元

数据(属性)。

# ls -l
总⽤量 12
-rwxr-xr-x. 1 root root 7438 "9⽉ 13 14:56" a.out
-rw-r--r--. 1 root root 654 "9⽉ 13 14:56" test.c

每⾏包含7列:

• 模式

• 硬链接数

• ⽂件所有者

• 组

• ⼤⼩

• 最后修改时间

• ⽂件名

ls -l读取存储在磁盘上的⽂件信息,然后显⽰出来

🔍 inode:文件的"基因库"

这个信息除了通过这种⽅式来读取,还有⼀个stat命令能够看到更多信息

[root@localhost linux]# stat test.c
File: "test.c"
Size: 654 Blocks: 8 IO Block: 4096 普通⽂件
Device: 802h/2050d Inode: 263715 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-09-13 14:56:57.059012947 +0800
Modify: 2017-09-13 14:56:40.067012944 +0800
Change: 2017-09-13 14:56:40.069012948 +0800

到这我们要思考⼀个问题,⽂件数据都储存在”块”中,那么很显然,我们还必须找到⼀个地⽅储存

⽂件的元信息(属性信息),⽐如⽂件的创建者、⽂件的创建⽇期、⽂件的⼤⼩等等。这种储存⽂件元信息的区域就叫做inode,中⽂译名为”索引节点”。

[ljh@lijunhua-alicloud stdio]$ ls -li
total 16
1052669 -rw-rw-r-- 1 ljh ljh 225 Oct 17 19:09
1052007 -rw-rw-r-- 1 ljh ljh 488 Oct 17 19:06
1052661 -rw-rw-r-- 1 ljh ljh 1496 Oct 17 19:11
1052662 -rw-rw-r-- 1 ljh ljh 447 Oct 17 18:53

每⼀个⽂件都有对应的inode,⾥⾯包含了与该⽂件有关的⼀些信息。为了能解释清楚inode,我们需要是深⼊了解⼀下⽂件系统。

🧬 inode数据结构解剖

inode就像文件的"DNA序列"🧬,在ext2文件系统中是这样定义的:

struct ext2_inode {__le16  i_mode;       /* File mode */__le16  i_uid;        /* Low 16 bits of Owner Uid */__le32  i_size;       /* Size in bytes */__le32  i_atime;      /* Access time */__le32  i_ctime;      /* Creation time */__le32  i_mtime;      /* Modification time */__le32  i_dtime;      /* Deletion Time */__le16  i_gid;        /* Low 16 bits of Group Id */__le16  i_links_count;/* Links count */__le32  i_blocks;     /* Blocks count */__le32  i_flags;      /* File flags */union {struct {__le32  l_i_reserved1;} linux1;struct {__le32  h_i_translator;} hurd1;struct {__le32  m_i_reserved1;} masix1;} osd1;              /* OS dependent 1 */__le32  i_block[EXT2_N_BLOCKS];/* Pointers to blocks */__le32  i_generation; /* File version (for NFS) */__le32  i_file_acl;  /* File ACL */__le32  i_dir_acl;   /* Directory ACL */__le32  i_faddr;     /* Fragment address */union {struct {__u8   l_i_frag;    /* Fragment number */__u8   l_i_fsize;   /* Fragment size */__u16  i_pad1;__le16  l_i_uid_high;   /* these 2 fields */__le16  l_i_gid_high;   /* were reserved2[0] */__u32  l_i_reserved2;} linux2;struct {__u8   h_i_frag;    /* Fragment number */__u8   h_i_fsize;   /* Fragment size */__le16  h_i_mode_high;__le16  h_i_uid_high;__le16  h_i_gid_high;__le32  h_i_author;} hurd2;struct {__u8   m_i_frag;    /* Fragment number */__u8   m_i_fsize;   /* Fragment size */__u16  m_pad1;__u32  m_i_reserved2[2];} masix2;} osd2;              /* OS dependent 2 */
};/** Constants relative to the data blocks*/
#define EXT2_NDIR_BLOCKS    12
#define EXT2_IND_BLOCK      EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK     (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK     (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS       (EXT2_TIND_BLOCK + 1)备注: EXT2_N_BLOCKS = 15

💡 关于inode的冷知识

  1. 唯一标识:每个inode号在分区内是唯一的,就像身份证号👤,Linux下,保存⽂件属性的集合叫做inode,⼀个⽂件,⼀个inode,inode内有⼀个唯⼀的标识符,叫做inode号。

  2. 固定大小:通常128或256字节,无论文件内容多大,任何⽂件的内容⼤⼩可以不同,但是属性⼤⼩⼀定是相同的。

  3. 内容分离:文件名不在inode中!它存储在目录文件里📁

 到⽬前为⽌,相信⼤家还有两个问题:

1. 我们已经知道硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,读取的基本单位

是”块”。“块”⼜是硬盘的每个分区下的结构,难道“块”是随意的在分区上排布的吗?那要怎

么找到“块”呢?

2. 还有就是上⾯提到的存储⽂件属性的inode,⼜是如何放置的呢?

⽂件系统就是为了组织管理这些的!!

知道的小伙伴可以在评论区讨论一下,不知道的小伙伴也没关系,下一篇博客立马向你解释!!! 

http://www.xdnf.cn/news/14329.html

相关文章:

  • 基于STM32单片机RLC检测仪
  • TabSyncer:浏览器标签页管理工具
  • 【freertos互斥量补充】递归锁
  • 1.18 进程管理PM2
  • 山东大学项目实训-创新实训-法律文书专家系统-项目报告(六)
  • 【数据结构中的堆】
  • ASR-PRO语音识别可能出现的问题
  • langchain从入门到精通(九)——ChatGPT/Playground手动模拟记忆功能
  • MFE微前端:如何捕捉远程应用的remote.js加载失败的错误?
  • 【人工智能数学基础】测度论
  • 11.OpenCV—联合QT环境配置
  • RTDETRv2 pytorch 官方版自己数据集训练遇到的问题解决
  • 正整数的正向分解
  • 股指期货的多空策略是什么?
  • 编译链接实战(30)strip移除了哪些内容
  • java设计模式[3]之结构性型模式
  • Druid 连接池详解
  • 基于CSO算法的任务卸载在IoT移动边缘计算
  • 绝对收敛 趋于 0 的速度足够快 | 条件收敛 --> 项趋于 0 正负项相互抵消
  • 语言模型的泛化能力和训练数据依赖性
  • Docker -- 快速入门
  • JavaScript 数据结构详解
  • Java垃圾回收机制
  • [NLP]课程期末知识点总结
  • [windows工具]PDFOCR识别导出Excel工具1.1版本使用教程及注意事项
  • 【JVM】- 类加载与字节码结构3
  • 性能优化 - 高级进阶:JVM 常见优化参数
  • Linux内核网络协议的双重注册机制:inet_add_protocol与inet_register_protosw深度解析
  • Python小酷库系列:Python中的JSON工具库(3)
  • 行为设计模式之State(状态)设计模式