Linux相关概念和易错知识点(20)(dentry、分区、挂载)

目录

1.dentry

(1)路径缓存的原因

(2)dentry的结构

①多叉树结构

②file和dentry之间的联系

③路径概念存在的意义

2.分区

(1)为什么要确认分区

(2)挂载

①进入分区

②被挂载的目录文件

(3)模拟创建分区

①创建特定大小的文件

②模拟创建分区

③挂载目录

④卸载分区

(4)总结


1.dentry

(1)路径缓存的原因

定位文件了实际上就是根据文件路径的逆向解析,从根目录(根目录的inode编号、名称等都是特殊固定的)开始一直按解析的路径依次打开目录文件,最终找到我们要访问的文件。每个文件都要有路径,而路径是进程告诉系统的(如cwd可以协助提供绝对路径)。但如果我们对同级目录的文件多次访问,每次访问都会不断重新从根目录打开文件,这样效率太低了。因此我们需要路径缓存

(2)dentry的结构

①多叉树结构

每个dentry都含有一个inode指针,指向内存中缓存的inode结构体。当系统启动的时候,根目录的dentry被最先创建。

每个文件都最多有一个dentry,整个系统的dentry链接为一棵多叉树

当进行任何路径访问时,会根据我们要访问的路径进入内存级dentry树里面找,如果找到了就直接根据inode信息打开文件;如果找不到,则会从能找到的结点(目录)开始,读取该节点内容到内存中,根据文件名找到对应的inode编号,再去创建file、缓存inode、创建dentry结点到内存中,并按树状连接到根,进入这个新的结点,以此类推直到找到文件。当找到路径最后指向的文件后就终止。此时我们可以得到fd并进行文件操作。

注意,path的存在是有意义的,它记录了根目录的dentry指针等信息,保证每次创建dentry时能够正确地连接到同一颗dentry多叉树里面,并对当前结点dentry进行管理。

我们不需要担心多叉树越来越大,因为Linux的内核链表允许dentry中的结点链入其它链表中。

②file和dentry之间的联系

我们的文件系统在硬件侧的逻辑就是fd -> file -> path -> dentry -> inode -> 根据inode结合GDT、超级块等读取Data blocks数据到内存 -> 根据内存已有数据决定新修改内容如何存储 -> 结合inode、GDT、超级块以数据块为最小单位写回磁盘 -> 更新管理信息。

其中dentry的作用就是帮助我们快速找到文件,当我们想要从fd访问文件时,我们只需要在dentry里面进行内存级访问、查找文件inode即可。第一次查找时可能会慢,因为要一直读取目录文件的内容(硬盘级操作),根据上级目录逐级创建dentry、inode结点,但第二次、第三次访问就可以很快的从根dentry找到自己重复访问的目录文件的inode(内存级操作),进一步快速打开文件。

③路径概念存在的意义

通过上面的学习,我们发现Linux需要对路径结构进行缓存。事实上,在磁盘上并没有路径的概念,也不存在目录文件和普通文件的区别,它只需要按照自己的结构存数据即可。路径的概念是操作系统建立的,路径本质就是一个针对硬盘存储进行管理的结构,Linux任何对路径的操作本质都是针对dentry的查找,构建等操作,dentry再和文件直接打交道。

一句话总结就是:硬盘的物理结构不存在路径,但系统的逻辑结构构建出了路径,dentry是提高路径访问效率的协助者。

2.分区

(1)为什么要确认分区

我们的dentry讲解中存在一个巨大的漏洞,那就是文件的inode是以分区为界限的。同一个操作系统能访问不同分区,这就使得inode编号的唯一性被打破了,我们又如何能使用inode的唯一性来查找文件呢?进一步讲,进程的路径真的只有我们理解的那样层层目录文件包含的关系吗?

问题的根源来自分区的确定,我们只要确定了分区,上面的问题就都能解释了。

(2)挂载

认识一下分区的查看

对于整个操作系统而言,尽管存在多个分区,但只有一个分区包含根目录,系统最开始就要加载根目录到内存中,创建dentry,后续的访问也都是根据根目录文件的内容来逐渐建立dentry多叉树的。但是这就再次陷入了刚才的问题,因此就必须引入挂载的概念。

①进入分区

如果不能进入分区,这块分区相当于不可用,因为根目录所在分区不能直接访问其它分区,这会导致inode混乱。我们要如何进入一个分区?

我们已经知道路径访问文件的途中本质就是不断打开目录文件,那么我们是否可以将分区和目录文件联系起来呢?可以的,我们称为把一个分区挂载到目录上。什么意思呢?就是说当我们将一个分区挂载到目录上后,这个目录会特殊处理,当我们打开这个目录文件时,系统不会真的去打开这个目录文件,而是直接进入了挂载的分区的根目录。

我们可以查看磁盘的挂载情况(Mounted on),其中我们发现/dev/cda1挂载到了根目录下,这也就意味着当我们打开根目录时,会直接进入dev1分区的根目录。进一步讲,当系统启动时,就会将系统文件所在分区挂载到根目录下。当访问根目录时,理所应当的就进入了根目录分区了。

②被挂载的目录文件

我们可以很简单地认为被挂载的目录文件就是很普通的目录文件,它有实体、有大小、有属性、inode也没什么特别的。就是因为它被我们用分区挂载了,所以它被识别为了一个挂载点,当我们访问时系统会特殊处理,不进入目录文件,而是进入挂载分区的根目录。

通过上面的知识,我们可以知道我们所见的根目录其实也是被分区挂载了一次、跳转了的,实际上的根目录并不在任何分区里,只不过这里涉及到的内核最底层,我们了解即可

当被挂载后,原来的目录文件不会有任何影响,只不过我们没办法打开它了,因为系统相当于为这个目录文件做了掩护,针对挂载点特殊处理了。我们看似是访问了这个目录文件,实际上是访问到了另外一个分区的根目录。这也提醒我们最好使用空目录来挂载分区,因为挂载后原来目录的内容会被隐藏。当然如果我们取消挂载,这个目录文件的内容依然可以正常显示,不会受到任何影响。

(3)模拟创建分区

我们可以通过模拟创建一个分区来加深对挂载的认识

①创建特定大小的文件

我们先创建一个普通文件,用来模拟一个分区。这里介绍一个指令dd,它可以快速构建一个特定大小的文件。它的主要功能是块级别复制,也就是说它会直接按照硬盘的数据块(自己指定,不一定是4KB)复制数据,而不会兼顾文件系统。这就会导致不同文件系统之间使用dd会存在兼容性问题,因为不同文件系统的管理、解读数据方式不同。这也就意味着dd适合磁盘备份、启动盘备份等操作,文件级别的复制还是cp更合适。

②模拟创建分区

我们得到一个文件后,要对它进行初始化,按照特定文件系统ext的格式将里面的GDT、blocks、bitmap等进行初始化,让它长得像一个分区

mkfs.ext可以快速帮我们格式化一个ext文件系统,会按照ext2的格式结合我们文件的大小自动将分区分为不同的块,初始化超级块等操作。

③挂载目录

我们可以进一步查看分区状况

之后我们便能正常使用这个模拟分区

④卸载分区

我们可以使用umount卸载分区,当用户正在使用分区时,或当用户的工作路径包含这个分区时,我们不能卸载这个分区,只有完全退出才可以操作。这也能解释我们永远无法卸载根目录,因为根目录永远在我们的cwd中,我们无法退出。


如果我们再挂载一次,会发现原来模拟分区里面的内容一点都没有修改,原来的文件和目录都还在

这进一步证明了挂载和删除挂载点都只是系统层面为解决不同分区访问的特殊处理,挂载操作本身不会对文件做出任何处理。当没有挂载时,分区存在,数据存在,只不过只有挂载之后,我们才有机会从Linux系统层面对它从根目录进行访问。

(4)总结

当我们cd进入某一个目录里时,有可能我们根本没有进入对应的目录文件(目录文件真实存在),而实际上进入了一个分区,这是通过挂载点进行特殊实现的。只有当分区挂载到某个路径,我们才能通过路径的形式访问分区。

路径 = 挂载点(分区) + 该分区创建的目录Shell进程的属性保存这些信息,即时判断当前的分区,针对性的解读inode或是根据文件系统进行不同操作即可。

所有路径都是从根目录开始挂载的,甚至我们看到的根目录也是经过一层挂载的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis 缓存击穿

目录 缓存击穿 什么是缓存击穿? 有哪些解决办法? 缓存穿透和缓存击穿有什么区别? 缓存雪崩 什么是缓存雪崩? 有哪些解决办法? 缓存预热如何实现? 缓存雪崩和缓存击穿有什么区别? 如何保…

电信网关配置管理系统 upload_channels.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

澳鹏通过高质量数据支持 Onfido 优化AI反欺诈功能

“Appen 在 Onfido 的发展中发挥了至关重要的作用,并已成为我们运营的重要组成部分。我们很高兴在 Appen 找到了可靠的合作伙伴。” – Onfido 数据和分析总监 Francois Jehl 简介:利用人工智能和机器学习增强欺诈检测 在当今日益数字化的世界&#xff…

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块,适用于执行简单的命令,不支持特殊符号 案列01,批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…

应对AI与机器学习的安全与授权管理新挑战,CodeMeter不断创新引领保护方案

人工智能(AI)和机器学习(ML)技术正在快速发展,逐渐应用到全球各类主流系统、设备及关键应用场景中,尤其是在政府、商业和工业组织不断加深互联的情况下,AI和ML技术的影响日益广泛。虽然AI技术的…

实现uniapp-微信小程序 搜索框+上拉加载+下拉刷新

pages.json 中的配置 { "path": "pages/message", "style": { "navigationBarTitleText": "消息", "enablePullDownRefresh": true, "onReachBottomDistance": 50 } }, <template><view class…

布谷直播源码部署服务器关于数据库配置的详细说明

布谷直播源码搭建部署配置接口数据库 /public/db.php&#xff08;2019年8月后的系统在该路径下配置数据库&#xff0c;老版本继续走下面的操作&#xff09; 在项目代码中执行命令安装依赖库&#xff08;⚠️注意&#xff1a;如果已经有了vendor内的依赖文件的就不用执行了&am…

【C++】STL— stack的常见用法和模拟实现

目录 1、stack的介绍 2、stack的使用 构造一个空栈 stack的简单接口应用 3、stack的模拟实现 4、栈的相关题目 4.1 最小栈 4.1.2思路 4.1.3 实现代码 4.2 栈的压入、弹出序列 4.2.2 思路 4.2.3程序实现 1、stack的介绍 在C中&#xff0c;stack是一种标准模板库&am…

vue大疆建图航拍功能实现

介绍 无人机在规划一块区域的时候&#xff0c;我们需要手动的给予一些参数来影响无人机飞行&#xff0c;对于一块地表&#xff0c;无人机每隔N秒在空中间隔的拍照地表的一块区域&#xff0c;在整个任务执行结束后&#xff0c;拍到的所有区域照片能够完整的表达出一块地表&…

[ DOS 命令基础 2 ] DOS 命令详解-网络相关命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

es自动补全(仅供自己参考)

elasticssearch提供了CompletionSuggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询效率&#xff0c;对于文档中字段的类型有一些约束&#xff1a; 查询类型必须是&#xff1a;completion 字段内容是多个补全词条形成的数组 P…

react jsx基本语法,脚手架,父子传参,refs等详解

1&#xff0c;简介 1.1 概念 react是一个渲染html界面的一个js库&#xff0c;类似于vue&#xff0c;但是更加灵活&#xff0c;写法也比较像原生js&#xff0c;之前我们写出一个完成的是分为html&#xff0c;js&#xff0c;css&#xff0c;现在我们使用react库我们把html和js结…

Chrome浏览器如何导出所有书签并导入书签

前言 我平常在开发中&#xff0c;基本是用的谷歌的浏览器&#xff0c;也就是Chrome&#xff0c;因为这个对于开发来说&#xff0c;比较友好。在开发中&#xff0c;包括调试接口&#xff0c;打断点&#xff0c;查看打印日志等&#xff0c;都是非常不错的。另一方面&#xff0c;…

[WSL][桌面][X11]WSL2 Ubuntu22.04 安装Ubuntu桌面并且实现GUI转发(Gnome)

1. WSL安装 这里不再赘述&#xff0c;WSL2支持systemd&#xff0c;如果你发现其没有systemd相关指令&#xff0c;那么你应该看看下面这个 https://blog.csdn.net/noneNull0/article/details/135950369 但是&#xff0c;Ubuntu2204用不了这个脚本&#xff0c;比较蛋疼。 – …

C语言中的 printf( ) 与 scanf( )

时隔多日&#xff0c;小编我又回来咯小编相信之前的博客能够给大家带来不少的收获。在我们之前的文章中&#xff0c;许多代码块的例子都用到了printf( ) 与 scanf( )这两个函数&#xff0c;大家都知道他们需要声明头文件之后才能使用&#xff0c;那这两个函数是什么呢&#xff…

【Homework】【1--4】Learning resources for DQ Robotics in MATLAB

Learning resources for DQ Robotics in MATLAB Lesson 1 代码 % Step 2: Define the real numbers a1 and a2 a1 123; a2 321;% Step 3: Calculate and display a3 a1 a2 a3 a1 a2; disp([a3 (a1 a2) , num2str(a3)])% Step 4: Calculate and display a3 a1 * a2 a3…

前端刺客系列----Vue 3 入门介绍

目录 一.什么是 Vue 3&#xff1f; 二.Vue 3 的主要特性 三,Vue3项目实战 四.总结 在前端开发的世界里&#xff0c;Vue.js 作为一款渐进式的 JavaScript 框架&#xff0c;已成为许多开发者的首选工具。自从 Vue 3 发布以来&#xff0c;它带来了许多重要的改进和新特性&…

Linux入门:环境变量与进程地址空间

一. 环境变量 1. 概念 1️⃣基本概念&#xff1a; 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#x…

2024版最新最全的Kali Linux操作系统安装使用教程(非常详细)超十万字解说Kali零基础入门到精通教程,收藏这一篇就够了

前言 这是向阳给粉丝盆友们整理的网络安全渗透测试入门阶段渗透测试工具Kali全套教程&#xff0c;本文超十万字超长分析&#xff0c;建议大家收藏慢慢学习&#xff01; 喜欢的朋友们&#xff0c;记得给向阳点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术 Ka…

【计网】基于TCP协议的Echo Server程序实现与多版本测试

目录 前言&#xff1a; 1、InitServer类的实现 1.1. 创建流式套接字 1.2. bind 绑定一个固定的网络地址和端口号 1.3.listen监听机制 1.4.完整代码 2. 循环接收接口与服务接口 2.1.accept函数讲解 讲个商场拉客的故事方便我们理解&#xff1a; 2.2.服务接口实现 3.服…