深入了解linux系统—— 操作系统的路径缓冲与链接机制

前言

在之前学习当中,我们了解了被打开的文件是如何管理的;磁盘,以及ext2文件系统是如何存储文件的。

那我们要打开一个文件,首先要先找到这个文件,操作系统又是如何去查找的呢?

理解操作系统搜索文件

1. 目录和文件名

我们知道:

  • 文件名是不作为文件属性存储在文件inode里的;
  • 在一个分区中,根据文件的inode值就可以找到该文件。

但是在之前的文件操作时,一种都是使用文件名进行对文件的相关操作,没有使用过文件inode值;

还用目录它是文件吗?

在这里插入图片描述

通过查看我们可以发现目录也是存在inode值的,那也就是说目录也是也文件;

文件 = 属性 + 内容,那目录的文件内容是什么呢?

首先属性不用多说;

目录文件的文件内容保存的是:文件名和inode号的映射关系。

  • 所以,访问文件时,必须打开当前工作目录,根据文件名获取对应的inode号,然后进行文件访问。
  • 所以,访问文件必须知道当前工作目录,本质就是必须打开当前工作目录文件,查看目录文件的内容获取要访问文件的inode号。

2. 路径解析

知道了访问当前工作目录下文件,要打开当前目录文件,查看当前目录文件内容;

那要打开当前工作目录,就要获取当前工作目录文件的inode号啊,如何获得呢?

很简单,打开上级目录,查看上级目录文件内容;那上级目录也是文件啊,要打开它也要知道它的inode号,那也要打开它的上级目录啊?

所以就一直访问上级目录,直到/根目录。

所以说:实际上,任何文件都存在路径;

比如:/home/lxb/linux/lesson8/code.c

这都要从根目录开始一次打开每一个目录文件,依次访问每个目录下的指定目录直到test.c文件(这个过程称之为Linux路径解析)

我们知道,访问文件本质就是进程去访问,在进程当中存在CWD当前工作路径;在我们open打卡指定文件时也给定了文件的路径。

所以我们访问文件必须要有目录+文件名(绝对路径)

3. 路径缓存

我们知道,文件都是在磁盘中存着的,那在Linux系统中存在真正的目录吗?

显而易见是不存在,只有文件;保存文件属性+内容。

在上述中,我们还了解到访问一个文件,都要从根目录/开始进行路径解析?

按道理来说是的,但是太慢了,在Linux系统中会缓冲历史路径结构。

Linux系统中,不存在目录,那在Linux系统中我们为什么可以看到目录路径结构?

打开的文件如果是目录,在系统中就在自己的内存中进行路径维护。

Linux系统中,内核里维护树状路径结构的内核结构体叫做:struct 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 hereso 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_PROFILINGstruct dcookie_struct *d_cookie; /* cookie, if any */
#endifint d_mounted;unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};
  • 每一个文件其实都有对应的dentry结构,包含普通文件;所以被打开的文件,在内存中就可以形成树状结构。
  • 整个树形节点也会同时属于LRU(Least Recently Used),在最近最少使用结构在,进行节点淘汰。
  • 同时也会属于Hash表,方便快速查找。
  • 这样有了树状结构,整体就有了Linux路径缓存结构,打开和访问任何文件,都先在该树下进行查找,找到了就返回inode和内容,没找到就从磁盘加载路径,添加到dentry结构中。

4. 挂载分区

在之前的描述中,都是在一个文件系统中,根据inode号查找文件,那inode号又不是跨分区的,如何根据inode确定是哪一个分区呢?

在分区写入文件系统后,我们没有办法直接使用;我们需要将文件系统与指定的目录进行关联(也就是挂载)才能使用

所以就可以根据我们访问目标文件的路径前缀来判断文件在哪一个分区。

这里关于挂载的相关操作,就不演示了;可以自己尝试一下。

软硬链接

1. 软链接

Windows中,我们可以给一个文件创建快捷方式,然后放到桌面,这样打开桌面的快捷方式就是打开文件了;

而在Linux系统中,我们也可以给文件创建快捷方式——就是软链接

ln -s code code.c

创建软链接文件code指向文件code.c;(可以说code文件是code.c的快捷方式)

在这里插入图片描述

软链接是一个独立的文件

2. 硬链接

我们直到一个目录中,存在...两个隐藏文件,.指向当前目录,..指向上级目录;

那也就是说,这些文件名都对应一个inode值。

这里...就是典型的硬链接。

而在内核中,记录了连接数:

在这里插入图片描述

创建硬链接:

ln 已存在文件 硬链接文件

在这里插入图片描述

这里要注意,我们只能给文件创建硬链接,不能给目录创建硬链接。

这里可能会感觉很奇怪,...不就是给目录创建硬链接吗?我们为什么不能创建?

这里还是为了避免循环路径问题,在内核中在路径搜索时,对...做了特殊处理,所以...不会造成循环路径问题;

而软链接,它是一个独立的文件,在路径遍历时不会把他当做目录文件来处理。

如果我们自己创建硬链接,就有可能造成循环路径问题。

3. 软硬链接的区别

  • 软链接是一个独立的文件
  • 硬链接只是文件名和目标文件的一组映射关系

4. 软硬链接的作用

  • 软链接就类似于快捷方式
  • 硬链接...,方便用户进程操作;文件备份。

到这里本篇文章内容就结束了,感谢各位大佬的支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84362.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker Hub仓库介绍

Docker Hub仓库全解析:从公共市场到私有化部署指南 一、Docker Hub公共镜像市场 1.1 核心功能解析 全球最大容器镜像库:累计托管超500万镜像核心服务矩阵: #mermaid-svg-CAMkhmtSWKEUw7z0 {font-family:"trebuchet ms",verdana,a…

redis使用RDB文件恢复数据

设置存盘间隔为120秒且10个key改变数据自动存盘使用RDB文件恢复数据 IP地址主机名192.168.10.170redis170 [rootredis170 ~]# yum install -y redis [rootredis170 ~]# systemctl start redis步骤一:设置存盘间隔为120秒且10个key改变自动存盘 [rootredis170 ~]#…

SpringBoot多环境配置文件切换

resources下application.yml、application-dev.yml、application-prod.yml多个配置文件。 spring:profiles:active: devspring:profiles:active: prod一般都是通过修改spring.profiles.active值来修改加载不同环境的配置信息,可以把切换的dev/prod放到pom.xml文件来…

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用 一、引言 在 Java 并发编程中,CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控…

【Java多线程】多线程状态下如何安全使用ArrayList以及哈希表

🔍 开发者资源导航 🔍🏷️ 博客主页: 个人主页📚 专栏订阅: JavaEE全栈专栏 多线程安全使用ArrayList 手动加锁 日常中最常用的方法,使用synchronized进行加锁,把代码打包成一份&a…

InnoDB引擎底层解析(二)之InnoDB的Buffer Pool(三)

Buffer Pool 实例 我们上边说过,Buffer Pool 本质是 InnoDB 向操作系统申请的一块连续的内存空间,在多线程环境下,访问 Buffer Pool 中的各种链表都需要加锁处理,在Buffer Pool特别大而且多线程并发访问特别高的情况下&#xff0…

Netty学习专栏(三):Netty重要组件详解(Future、ByteBuf、Bootstrap)

文章目录 前言一、Future & Promise:异步编程的救星1.1 传统NIO的问题1.2 Netty的解决方案1.3 代码示例:链式异步操作 二、ByteBuf:重新定义数据缓冲区2.1 传统NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解决方案2.3 代码示例:…

Vue3逐步抛弃虚拟Dom,React如何抉择

虚拟DOM:前端界的替死鬼 这玩意儿就是个前端开发的充气娃娃! 你以为它很牛逼?无非是给真DOM当替死鬼! 每次数据变,虚拟DOM先搁内存里自嗨一顿,diff算法跟便秘似的算半天,最后才敢碰真DOM。 说白…

分布式锁总结

文章目录 分布式锁什么是分布式锁?分布式锁的实现方式基于数据库(mysql)实现基于缓存(redis)多实例并发访问问题演示项目代码(使用redis)配置nginx.confjmeter压测复现问题并发是1,即不产生并发问题并发30测试,产生并发问题(虽然单实例是synchronized&am…

解决自签名证书HTTPS告警:强制使用SHA-256算法生成证书

解决自签名证书HTTPS告警:强制使用SHA-256算法生成证书 一、问题场景 在使用OpenSSL生成和配置自签名证书时,常遇到以下现象: 浏览器已正确导入根证书(.pem文件),但访问HTTPS站点时仍提示不安全连接或证…

线上 Linux 环境 MySQL 磁盘 IO 高负载深度排查与性能优化实战

目录 一、线上告警 二、问题诊断 1. 系统层面排查 2. 数据库层面分析 三、参数调优 1. sync_binlog 参数优化 2. innodb_flush_log_at_trx_commit 参数调整 四、其他优化建议 1. 日志文件位置调整 2. 生产环境核心参数配置模板 3. 突发 IO 高负载应急响应方案 五、…

window 显示驱动开发-初始化和 DMA 缓冲区创建

若要指示 GPU 支持 GDI 硬件加速,显示微型端口驱动程序的 DriverEntry 函数实现必须使用指向驱动程序实现的 DxgkDdiRenderKm 函数的指针填充 DRIVER_INITIALIZATION_DATA 结构的 DxgkDdiRenderKm 成员。 DirectX 图形内核子系统调用 DxgkDdiRenderKm 函数&#xf…

Go语言实战:使用 excelize 实现多层复杂Excel表头导出教程

Go 实现支持多层复杂表头的 Excel 导出工具 目录 项目介绍依赖说明核心结构设计如何支持多层表头完整使用示例总结与扩展 项目介绍 在实际业务系统中,Excel 文件导出是一项常见功能,尤其是报表类需求中常见的复杂多级表头,常规表格组件往…

机器视觉6-halcon高级教程

机器视觉6-halcon高级教程 双目立体视觉原理视差外极线几何双目标定 双目立体视觉之Halcon标定一.标定结果二.Halcon标定过程1.获取左右相机图像中标定板的区域;2.提取左右相机图像中标定板的MARK点坐标和摄像机外部参数;3.执行双目标定;4.获取非标准外极线几何到标…

板凳-------Mysql cookbook学习 (六)

2025年Pytorch-gpu版本安装(各种情况适用自己的安装需求,亲测绝对有效,示例安装torch2.6.0,过程详细面向小白)_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查错 import s…

Spring boot和SSM项目对比

目录对比 springboot目录 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置类│ │ │ │ ├─controller // 存放控制器类│ │ │ │ ├─entity // 存…

《关于浔川社团退出DevPress社区及内容撤回的声明》

《关于浔川社团退出DevPress社区及内容撤回的声明》 尊敬的DevPress社区及读者: 经浔川社团内部决议,我社决定自**2025年5月26日**起正式退出DevPress社区,并撤回所有由我社成员在该平台发布的原创文章。相关事项声明如下: …

Python性能优化利器:__slots__的深度解析与避坑指南

核心场景:当需要创建数百万个属性固定的对象时,默认的__dict__字典存储会造成巨大内存浪费。此时__slots__能通过元组结构取代字典,显著提升内存效率(实测节省58%内存)! 底层原理:为何能节省内…

Go 语言中的 Struct Tag 的用法详解

在 Go 语言中,结构体字段标签(Struct Tag) 是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如 JSON、XML)、ORM 映射、验证等场景。你在开发 Web 应用或处理数据交互时&a…

微软正式发布 SQL Server 2025 公开预览版,深度集成AI功能

微软在今年的 Build 2025 大会上正式发布了 SQL Server 2025 公开预览版,标志着这一经典数据库产品在 AI 集成、安全性、性能及开发者工具方面的全面升级。 AI 深度集成与创新 原生向量搜索:SQL Server 2025 首次将 AI 功能直接嵌入数据库引擎&#xff…