| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 第十三章------虚拟文件系统 -> 正文阅读 |
|
[系统运维]第十三章------虚拟文件系统 |
虚拟文件系统是VFS,内核提供了文件和文件相关的接口。系统中所有文件不但依赖VFS共存,还依赖VFS协调工作。 通用的文件接口,包括read write和open这一类接口,我们可以使用这些接口进行文件 、硬盘读取。 之所以能够使用统一的接口对文件进行读写,是因为linux提供了统一的抽象层 1.unix文件系统unix使用了4种抽象概念:文件、目录、索引点 2.VFS对象以及数据结构VFS 主要有四个对象,他们分别是 超级块对象 索引节点对象 目录对象 文件对象 目录是另一种形式的文件,VFS把目录当成文件来处理 四个对象分别为: super_operation 对象,其中包括特定文件所能调用的方法 inode_operation对象,其中包括内核针对特定文件所能调用的方法,包括create和link dentry_operation对象,其中包括特定目录能调用的方法,比如d_compare和d_delete file_operation 对象,针对已经打开的文件所能调用的方法,read 或者write open等。 3.超级块对象各种文件系统都必须实现超级块对象,该对象用于存储特定文件系统信息,通常对应与存放在特定磁盘待定扇区中的文件系统超级块或文件系统控制块。对于并非基于磁盘的文件系统,他们会在现场创建超级块并放在内存中
超级块操作: 如果一个系统要写自己的超级块,则需要调用:
看到这里我会思考,什么情况下会写超级块 其中操作方法 s_op 对每个文件系统来说,是非常重要的,它指向该超级块的操作函数表,包含一系列操作方法的实现,这些方法有:
下面看一下超级块的用法 struct inode *alloc_inode(struct_block* sn); 在给定的超级块下创建和初始化一个新的索引节点对象 释放给定的索引点 void destroy_inode(struct inode *inode); 索引节点脏的时候会调用这个函数 void dirty_inode(struct inode* inode); 给定的索引点写入磁盘 void write_inode(struct inode* inode, int wait); 最后一个索引点被释放后会触发这个函数 drop_inode(struct inode* inode); 从磁盘上删除索引点 delete_inode(struct inode* inode) 给定的超级块更新磁盘上的超级块,调用者必须一致持有s_lock锁 void write_super(struct super_blokck* sb); 使文件系统的数据源和磁盘上的文件系统同步,wait参数指定是否要同步 void sync_fs(struct super_block* sb, int wait); 首先禁止对文件系统做改变,再使用给定的超级块更新磁盘上的超级块 void write_super_lockfs(struct super_block *sb); 对文件系统解除锁定,他是write_super_lockfs的逆操作 void unlokcfs(struct super_block *sb); 通过调用这个函数来获取文件状态。指定文件系统中相关的统计信息放到statfs中。 int statfs(struct super_block* sb, int *flags, char* data); 重新安装文件系统时候会调用这个函数 int remount_fs(struct super_block* sb, int *flags, char* data); 调用这个函数释放索引点 void clear_inode(struct inode* inode); 调用这个函数终端安装操作,这个函数一般被网络程序使用 umount_begin(struct super_block *sb); 以上所有函数都由VFS在进程上下文中调用 思索,我在平时工作中好像并没有接触到超级块,他是如何伴随着我们的日常的?linux超级块的全貌是什么样子的? 我认为其实它也是块设备的一种 首先要知道超级块是什么? 超级块是元数据的一部分,其中包含有关块设备上文件系统的信息。 Superblock提供以下有关文件,二进制文件,dll,元数据等的信息。 1)超级块,文件系统中第一个块被称为超级块。这个块存放文件系统本身的结构信息。比如,超级块记录了每个区域的大小,超级块也存放未被使用的磁盘块的信息。 Linux中存在着很多的文件系统,比如常见的ext2,ext3,ext4,sysfs,rootf,proc等等,一个超级块其实就对应一个独立文件系统 超级块有什么作用? 每个文件系统都有一个超级块结构,每个超级块都要链接到一个超级块链表。而文件系统内的每个文件在打开时都需要在内存分配一个inode结构,这些inode结构都要链接到超级块。 看完了我觉得linux超级块像windows的c盘,不过linux比较隐晦,不会暴漏给用户这些底层概念 4.索引节点对象索引节点对象包含了内核在操作文件或者目录时候的全部信息,如果没有这些信息,那么不管这些信息在磁盘上怎么存放的,必须从磁盘读取所有信息-------也就是说这些信息记录在inode上,可以加快读取,直接去内存读,而不用去磁盘读 ? i_bdev指向的是块设备结构体 c_dev 指向的就是字符串设备结构体 索引点操作对象 ?操作函数如下: VFS通过系统调用create、open来调用这个函数,从而为dentry对象创建一个索引节点。创建的时候使用mode的初始模式 int create(struct inode* dir, struct dentry* dentry, int mode) 在特定目录寻找索引节点,这个索引几点对应dentry中的文件名 struct dentry * lookup(struct inode* dir, struct dentry * dentry) 还有很多我们常见的 link、unlink、symlink、mkdir、rmdir、readlink 就不多说了 mknod是一个有意思的命令 mknod 命令建立一个目录项和一个特殊文件的对应索引节点。 ? mknod 还可以创建设备文件 ? ? 我看到这里有点乱,索引节点对象到底是做什么的是跟目录有关还是文件? 根据百度百科,提取一些关键介绍 linux文件系统将文件索引节点号和文件名同时保存在目录中。 所以,目录只是将文件的名称和它的索引节点号结合在一起的一张表,目录中每一对文件名称和索引节点号称为一个连接。对于一个文件来说有唯一的索引节点号与之对应,对于一个索引节点号,却可以有多个文件名与之对应。因此,在磁盘上的同一个文件可以通过不同的路径去访问它。? 我们先看第一个data 目录
再看data目录下的index.html和test.log
这就很好解释了,所以,目录只是将文件的名称和它的索引节点号结合在一起的一张表,每一个文件都有自己的node id号 5.目录项对象VFS 把 目录和文件都当作文件来看待,比如说/bin/vi? 是两个文件 bin 文件 和 vi文件,不过linux把目录当成一个特殊文件,方便搜索罢了 目录项对象格式: ?目录状态有三种状态,未被使用、被使用和负状态 负状态只是一个标识位,因为索引节点被删掉。目录项可能不正确了,但是索引节点依然保留,仍然是有效对象 目录项是有缓存的,目录项缓存由三部分组成: 1.被使用的目录项链表。该链表通过索引节点的i_dentry项连接相关的索引节点,因为给定的索引节点可能由多个目录项对象,所以要使用链表 2.最近被使用的双向链表,这个链表含有未被使用和负状态的目录对象。由于这个链表总是从头部插入目录项。所以链表头部总是比尾部要新,当内部节点必须要删除节点的时候,要从尾部开始删除 3.散列表和相应的散列函数用来快速的给定路径解析为相关的目录项对象。 散列数组dentry_hashtable 表示,每一个元素都是指向具有相同健值的目录项对象链表的指针。 目录项操作很简单: ? 判断目录对象是否有效,大部分文件系统将他们设置为null,因为他们认为dcache总是有效的 int d_revalidate(struct dentry *dentry, struct nameidate*) 该函数将目录生成散列表,将这个目录项加入散列表中 int d_hash(struct dentry* dentry, struct qstr* name); 将name1 和 2比较,注意需要加dcache_lock int d_compare(struct dentry* dentry, struct qstr *name1, struct qstr *name2); 当目录项计数器为0的时候,系统会调用这个函数 int d_delete(struct dentry* dentry); 目录对象将要被释放的时候调用这个函数 void d_release(struct dentry* dentry); 当一个目录项对对象丢失了其相关节点时候,vfs使用这个函数。 void d_input(struct dentry* dentry, struct inode* inode); 6.文件对象文件对象表示进程已经打开的文件。进程直接操作的就是i文件对象,open 创建 close 关闭 操作函数也不多写了,实在是比较熟悉了 ? ? 内核使用一些标准的数据结构来管理文件系统的其他相关数据结构 ? ?每种文件系统都只有一个file_system_type 结构 当一种文件系统被安装的时候,会创建一个vfsmount 结构 我之前很多次都说过,每个进程都会维护一个fd_table 里面会维护fd和实际物理介质的关系 ? ?fs_struct 进程相关的第二个结构fs_struct,它包含文件系统和进程相关的信息 ?这个结构包含了当前进程的工作目录和根目录。 第三个目录结构是namespace结构体,由进程描述符mmt_namespace域指向 list 是已安装系统的双向链表 每个进程都维护一个count作为引用计数,防止其他进程在用这个数据结构的时候被析构 默认情况下所有进程都使用相同的命名空间,只有在clone的时候才会使用CLONE_NEW标志,才会给进程一个唯一的命名空间拷贝结构体。大多数进程都是相同的默认命名空间 有点好奇,这是不是K8s里的命名空间呢?哈哈哈哈? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 6:32:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |