尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Linux之ext文件系统

Linux之ext文件系统
📅 发布时间:2026/7/31 22:54:24

1.目录与文件名

我们再使用linux中用的都是文件名而不是inode,那么这是怎么实现的???

inode 内部不存储文件名!inode 只保存文件元数据:权限、大小、时间戳、磁盘块指针。文件名存放在目录文件的数据块中。

  1. 目录本质依然是文件。 普通文件的数据块存放业务数据;目录文件的数据块专门存储一张映射表:文件名 <----> inode编号。
  2. 硬链接原理依托这个结构: 多个不同文件名指向同一个 inode,就是硬链接。删除文件rm,本质是删掉目录里一条文件名-inode映射,只有 inode 引用计数归 0,磁盘数据才会被回收。
  3. .与..目录创建时自动写入两条记录:.指向自身 inode、..指向父目录 inode,也就是内核自动维护的目录硬链接。用户无法手动创建目录硬链接,防止环路死循环。

通俗理解:inode 是文件本体;目录里的文件名只是找到本体的 “标签”。一个本体可以贴多个标签(硬链接)。

关键问题:目录 r/w/x 权限特殊含义

普通文件权限:

  • r:读取内容
  • w:修改内容
  • x:执行文件

目录权限完全不一样!

  1. r 权限:可以读取目录内的映射表(可以执行 ls,看到有哪些文件名)
  2. w 权限:允许修改目录内映射表 也就是:新建文件、删除文件、重命名文件(修改映射条目)
  3. x 权限:允许穿越目录,进入目录,访问目录内文件对应的 inode
# 给所有者增加执行权限 chmod u+x test.sh # 取消其他用户写权限 chmod o-w log.txt # 设置所有人只读 chmod a=r file # 用户读写,组读,其他无权限 chmod u=rw,g=r,o= file
eg

执行命令:cat test.c

  1. shell 接收字符串test.c;
  2. 操作系统去当前目录文件的数据块查找映射表,匹配字符串test.c,拿到对应的 inode 号;
  3. 根据 inode 编号,在磁盘找到对应的 inode 结构体;
  4. 读取 inode 里的数据块指针,找到磁盘数据块;
  5. 将数据读出,打印到屏幕。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <dirent.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <directory>\n", argv[0]); exit(EXIT_FAILURE); } DIR *dir = opendir(argv[1]); if (!dir) { perror("opendir"); exit(EXIT_FAILURE); } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // 跳过 . 和 .. if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } printf("Filename: %s, Inode: %lu\n", entry->d_name, (unsigned long)entry->d_ino); } closedir(dir); return 0; }

2.路径解析

问题:打开当前工作目录文件,查看当前工作目录文件的内容?当前工作目录不也是文件吗?我们访问当前工作目录不也是只知道当前工作目录的文件名吗?要访问它,不也得知道当前工作目录的inode吗?
答案1:所以也要打开:当前工作目录的上级目录,额....,上级目录不也是目录吗??不还是上面的问题吗?
答案2:所以类似"递归",需要把路径中所有的目录全部解析,出口是"/"根目录。
最终答案3:而实际上,任何文件,都有路径,访问目标文件,

什么是路径解析?

当我们调用open("/a/b/c.txt"),内核无法直接通过字符串找到文件,必须逐层拆解路径、逐级查询目录,这个过程就是路径解析。

完整流程示例:/home/user/test.log

  1. 定位根目录/的 inode;
  2. 读取根目录的数据块,遍历目录映射表,查找名称home,得到 home 目录 inode;
  3. 读取 home 目录的数据块,查找user,拿到 user 目录 inode;
  4. 读取 user 目录数据块,查找test.log,获取目标文件 inode;
  5. 使用 inode 访问文件元数据与文件数据块。

然而每次找文件位置都这样是很不方便的,会花费大量的时间,所以系统会将文件路径缓存起来,但是很多很多的缓存就要先描述再组织

3.路径缓存

dentry 全称 Directory Entry(目录项)。

  1. 磁盘上的 dentry:目录文件数据块内文件名-inode号的原始记录。
  2. 内存中的 dentry 缓存:内核把常用目录项加载进内存,构建内存哈希表。
struct dentry { atomic_t d_count; unsigned int d_flags; /* protected by d_lock */ spinlock_t d_lock; /* per dentry lock */ struct inode *d_inode; /* Where the name belongs to - NULL is * negative */ /* * The next three fields are touched by __d_lookup. Place them here * so they all fit in a cache line. */ struct hlist_node d_hash; /* lookup hash list */ struct dentry *d_parent; /* parent directory */ struct qstr d_name; struct list_head d_lru; /* LRU list */ /* * d_child and d_rcu can share memory */ union { struct list_head d_child; /* child of parent list */ struct rcu_head d_rcu; } d_u; struct list_head d_subdirs; /* our children */ struct list_head d_alias; /* inode alias list */ unsigned long d_time; /* used by d_revalidate */ struct dentry_operations *d_op; struct super_block *d_sb; /* The root of the dentry tree */ void *d_fsdata; /* fs-specific data */ #ifdef CONFIG_PROFILING struct dcookie_struct *d_cookie; /* cookie, if any */ #endif int d_mounted; unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ };

缓存带来的优化

下次访问同一文件,不需要再次读取磁盘目录块: 直接在内存 dentry 哈希表中匹配文件名,快速拿到 inode,省去大量磁盘 IO。

dentry 生命周期

  • 活跃文件:dentry 长期驻留内存;
  • 内存紧张时:内核回收不常用的 dentry 缓存;
  • 文件删除 / 重命名:对应 dentry 失效。

重谈inode编号和块号

a.inode编号和块号:不是组内有效,是整个分区内有效,唯一(inode)

b.再一个分区内,一个文件系统内部有多少个数据块,inode是固定的,提前设计好的

根据块号和inode通过计算可以找到相应的组

如果我要访问我当前的文件内容分或者属性,首先要打开当前目录,访问当问目录的数据块

eg:

以读取/home/test/log.txt举例:

  1. 从根目录/开始,找到根目录 inode;
  2. 读取根目录 inode 对应目录数据块;目录块内存放一张「文件名 → inode 编号」映射表(dentry 原始磁盘存储形式);
  3. 在根目录块中查找名称home,拿到home目录 inode;
  4. 读取 home 目录 inode 的数据块,查找test,拿到 test 目录 inode;
  5. 读取 test 目录数据块,查找log.txt,得到目标文件 inode 编号;
  6. 读取log.txt的 inode:
    • inode 中存放文件元数据(大小、权限、时间);
    • inode 内部磁盘块指针,指向存放真实文本内容的数据块;
  7. 读取数据块,最终拿到文件内容。
1. 你怎么知道文件属于哪一个文件系统?
super_block(超级块)

每一块磁盘分区被挂载后,内核会创建一个超级块实例struct super_block,代表一个独立文件系统(ext4/xfs/tmpfs 等)。

完整链路
  1. 挂载流程:mount命令读取分区超级块,在内核生成super_block;
  2. 对象关联关系
    • inode->i_sb:每个 inode 内部自带指针,指向所属文件系统的超级块;
    • dentry->d_inode→inode→super_block;
    • struct file通过 dentry/inode 最终可以追溯到super_block。
  3. 超级块记录信息:
    • 文件系统类型(ext4、tmpfs、btrfs)
    • 挂载点、块大小、最大 inode 编号、文件系统专属操作函数集
  4. 用户态验证方式
    • statfs()系统调用,可以获取文件所在文件系统信息;
    • 命令:df 文件路径、mount查看挂载列表。

inode 绑定 super_block,顺着 inode 就能定位文件归属的文件系统。


2. 存储大文件问题
问题本质:inode 不直接存储文件内容,只保存元数据

inode 中存放磁盘块指针,用来找到存放文件真实数据的磁盘块。 ext 经典三级索引模型:

  1. 直接块:直接指向数据块;适合小文件,寻址速度最快
  2. 一级间接块:块内存放一批数据块编号
  3. 二级间接块:指向一级间接块列表
  4. 三级间接块:超大文件使用
#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)

硬链接

硬链接是什么

我们观察到他们的inode编号是一样的,也就是说明,这两个文件其实是同一个文件

mylog就是原来文件的别名,

所以建立硬链接的本质就是再当前目录下新建一个新的字符串(文件名)和目标文件的映射关系

蓝色框内就是说明有几个文件指向他

为什么要有??

删除文件要删除文件名和inode的映射关系,所以硬链接数为1,时删除文件才真正把文件删除

1.删除旧备份不会损坏现存数据

每日轮换备份示例:保留最近 7 天备份。 当需要清理最旧一天备份时: 我们只需要删除旧备份目录下的所有硬链接(unlink)。 只要其他备份快照依然持有 inode 硬链接计数,磁盘上真实文件数据不会被删除。 完美实现滚动清理旧备份,不会误删其他快照里的文件。

现在将其删除

但是不用害怕,文件的备份依然存在


为什么目录的硬链接是2,普通文件硬链接是1

1. 普通文件log链接数 = 1

执行touch log,只产生1 条 dentry:当前目录下的文件名log。 没有额外名字指向这个 inode,所以计数 = 1。 只有手动ln log log_hard创建硬链接,数值才会上涨。

2. 新建目录dir链接数 = 2

mkdir dir自动生成两个 dentry 指向 dir 的 inode:

  1. dir:上层目录(homework)里的目录名;
  2. .:dir 目录内部的当前目录符号。

所以刚创建完毕,链接计数直接是 2。

我们再dir下面在创建ddir发现文件dir的硬链接变多了,因为ddir的隐藏文件..是dir的硬链接

所以. .. 本质上是硬链接

硬链接不能给目录建立,防止用户行程环形路径,进入死循环.

软连接

ln -s test.c test-soft

是什么

软连接是一个独立的文件

文件=内容+属性

软连接文件的内容存的是指向目标文件的路径

为什么

现在我的可执行文件myexe再很深的目录下面

这样执行就不方便所以我们可以采用软连接,达到便捷的效果

软连接类似于windows下面的快捷方式

相关新闻

  • 品牌商标维权必学!商标维权完整执行流程(官方正规步骤)
  • 如何在Unity中快速搭建跨平台TUIO模拟器开发环境
  • 2026年动物医学助学小自考本科-华中农业大学助学中心 - Luckyone王

最新新闻

  • 核工业高辐射场景监控选型:耐辐射镜头厂家横向对比(国产化替代实测推荐)
  • 如何让老旧电视重获新生?mytv-android安卓电视直播软件终极指南
  • RAG-Anything:如何用统一框架解决企业多模态知识管理挑战
  • 2026年8月涉财产争议处理:如何匹配对应专业法律服务机构 - 好物分享知识传播
  • 5分钟快速上手Teable:AI原生无代码数据库的完整入门指南
  • 2026苏州APP定制公司实力测评 - IT超人老张

日新闻

  • 7步掌握KMS智能激活工具:Windows和Office永久激活完整方案
  • 如何在Windows上运行iOS应用:ipasim跨平台模拟器终极指南
  • 2026年重庆工伤赔偿律师口碑推荐:洪家木律师用专业赢得信赖 - 本地品牌推荐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号