下载做蛋糕网站,wordpress吗,做网站设计是什么专业,厦门市建设局报表网站目录 1.dentry
#xff08;1#xff09;路径缓存的原因
#xff08;2#xff09;dentry的结构
①多叉树结构
②file和dentry之间的联系
③路径概念存在的意义
2.分区
#xff08;1#xff09;为什么要确认分区
#xff08;2#xff09;挂载
①进入分区
②被挂…目录 1.dentry
1路径缓存的原因
2dentry的结构
①多叉树结构
②file和dentry之间的联系
③路径概念存在的意义
2.分区
1为什么要确认分区
2挂载
①进入分区
②被挂载的目录文件
3模拟创建分区
①创建特定大小的文件
②模拟创建分区
③挂载目录
④卸载分区
4总结 1.dentry
1路径缓存的原因
定位文件了实际上就是根据文件路径的逆向解析从根目录根目录的inode编号、名称等都是特殊固定的开始一直按解析的路径依次打开目录文件最终找到我们要访问的文件。每个文件都要有路径而路径是进程告诉系统的如cwd可以协助提供绝对路径。但如果我们对同级目录的文件多次访问每次访问都会不断重新从根目录打开文件这样效率太低了。因此我们需要路径缓存
2dentry的结构
①多叉树结构 每个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或是根据文件系统进行不同操作即可。
所有路径都是从根目录开始挂载的甚至我们看到的根目录也是经过一层挂载的。