Linux虚拟文件系统(VFS)

虚拟地址空间通常是与进程密切相关的概念,而不是文件系统。虚拟地址空间是为了提供进程对内存的抽象和隔离而设计的。

文件系统不使用页表,直接使用物理地址。

虚拟文件系统是linux内核的一个核心子系统。、

虚拟文件系统的目的:通过一个抽象层,存储设备使用不同的文件系统都可以通过相同的接口访问:open(),red(),write();
在这里插入图片描述

文件系统抽象层

linux能支持各种文件系统,就是因为有文件系统抽象层。
调用过程:write(fd,buf,len);
用户空间write()->虚拟文件系统sys_write()->硬件的文件系统的写方法——>物理介质

Unix文件系统

Unix使用了四种文件系统的抽象概念:文件,目录项,索引节点和安装点(mount point)。
在Unix中,目录属于普通文件,它列出包含在其中的所有文件。

inode和元数据

Unix把文件的相关信息和文件本身这两个概念加以区分,已经是说,文件的元数据(控制权限,大小,创建者。。)被存储在一个单独的数据结构中,该结构被称为索引节点(inode:index node的缩写)。

将元数据和实际数据分开存储是一种思想

Unix文件系统,在物理磁盘布局中也是按照这种思想实现的,在磁盘上,文件(目录也是文件)的元数据存储在单独的几个块中(按照索引顺序)。
控制信息被集中存储在磁盘的超级块中。

VFS对象及数据结构

VFS采用的是面向对象。使用一组数据结构来代表通用文件对象。
VFS主要有四个对象类型:

  1. 超级块对象,它代表一个已安装的文件系统
  2. 索引节点对象,它代表一个具体文件(可以是目录文件)。
  3. 目录项对象,目录项。
  4. 文件对象,有对象打开的文件。
    每个数据结构其中都包含操作函数(以函数指针的形式存储在数据结构中)。

超级块对象

每个文件系统都必须实现超级块对象,存储文件系统的信息,通常对应于存放在磁盘特定扇区中的文件系统超级块。不基于磁盘的文件系统,会在使用时动态创建超级块。

struct super_block {
    /* 文件系统特定的信息和操作 */
    const struct super_operations  *s_op;  // 文件系统特定的超级块操作
    struct dquot_operations        *dq_op; // 磁盘配额操作
    struct quotactl_ops            *s_qcop; // 磁盘配额控制操作
    const struct export_operations *s_export_op; // 导出操作

    /* 与文件系统相关的全局信息 */
    unsigned long           s_flags;      // 超级块标志
    const char              *s_id;         // 文件系统的唯一标识符
    unsigned int            s_blocksize;   // 块大小
    unsigned char           s_blocksize_bits; // 块大小的位数
    unsigned char           s_dirt;        // 超级块的脏标志
    int                     s_count;       // 超级块的引用计数
    atomic_t                s_active;      // 超级块的活跃引用计数
    struct hlist_head       s_inode_lru;   // 超级块关联的Inode的LRU链表头
    struct list_head        s_list;        // 全局超级块链表
    struct list_head        s_instances;   // 文件系统实例链表

    /* 与文件系统类型相关的信息 */
    const struct file_system_type *s_type; // 文件系统类型
    const struct fs_context_operations *s_fs_info; // 文件系统信息
    struct fscrypt_info    *s_cop; // 文件系统加密信息

    /* 与底层存储介质相关的信息 */
    struct block_device    *s_bdev; // 超级块对应的块设备
    struct backing_dev_info *s_bdi; // 超级块的后备设备信息

    /* 文件系统挂载点的信息 */
    struct mtd_info        *s_mtd; // 关联的Memory Technology Device(MTD)信息
    struct gendisk         *s_disk; // 关联的块设备信息
    struct hlist_head      s_dentry_lru; // 超级块关联的Dentry的LRU链表头

    /* 其他字段和操作省略... */
};

索引节点对象:存储文件的元数据

内核是根据索引节点对象的信息来操作文件的。
对于Unix风格的文件系统,这些信息可以从磁盘读入。没有索引对象信息,则需要现场创建。

struct inode {
    umode_t               i_mode;      // 文件的权限和类型
    unsigned short        i_opflags;   // 操作标志
    kuid_t                i_uid;       // 文件的用户标识符
    kgid_t                i_gid;       // 文件的组标识符
    dev_t                 i_rdev;      // 设备文件的设备号
    loff_t                i_size;      // 文件大小
    struct timespec       i_atime;     // 最后访问时间
    struct timespec       i_mtime;     // 最后修改时间
    struct timespec       i_ctime;     // 最后状态改变时间
    struct super_block   *i_sb;        // 超级块指针
    const struct inode_operations *i_op; // Inode 操作
    struct file_operations *i_fop;     // 文件操作
    struct address_space *i_mapping;    // 地址空间对象:即文件的内存中的位置信息
    unsigned long         i_ino;       // 文件的 inode 号
    atomic_t              i_count;     // 引用计数
    unsigned int          i_flags;     // Inode 标志
    struct list_head      i_wb_list;   // 写回列表
    struct list_head      i_lru;       // LRU 列表
    struct list_head      i_sb_list;   // 超级块链表
    struct hlist_node     i_hash;      // Inode hash 链表
    struct dquot          *i_dquot[MAXQUOTAS]; // 磁盘配额
    struct file_lock      *i_flock;     // 文件锁
    unsigned long         i_state;      // Inode 状态
    struct mutex          i_mutex;     // Inode 互斥锁
    struct rw_semaphore   i_alloc_sem;  // Inode 分配信号量
    // 其他字段和操作省略...
};

一个索引节点也可以代表设备或者管道这样的特殊文件。

目录项对象:在磁盘中没有对应的数据结构

目录项对象就是为了方便查找操作而引入的,真正操作文件还需要inode对象。
VFS根据字符串形式的路径名现场创建它,其没有真正保存在磁盘上,所以目录项结构体没有是否被修改的标志(不需要写回磁盘)。

文件对象

表示进程已打开的文件。进程直接处理的是文件对象。
文件是已打开的文件在内存中的表示。该对象由open()系统调用创建,由close()系统调用撤销。
文件对象只在进程层面表示已打开的文件,但其指向的对应的索引节点和目录项对象是唯一的。

struct file {
    struct file_operations *f_op;    // 文件操作函数指针集合
    loff_t f_pos;                    // 文件当前位置(偏移量)
    struct inode *f_inode;           // 与文件关联的 inode 结构体指针
    struct address_space *f_mapping; // 文件地址空间指针
    unsigned int f_flags;            // 文件状态和标志
    struct file_ra_state f_ra;       // 文件预读取状态
    void *private_data;              // 指向文件特定私有数据的指针
    // 其他字段和操作省略...
};

其通过访问inode对象来操作文件。

和进程有关的数据结构

每一个进程都有一组自己打开的文件。有两个数据结构将VFS层和系统进程紧密联系。

进程自己打开的文件

struct files_struct {
    atomic_t count;               // 引用计数
    struct fdtable *fdt;          // 指向文件描述符表的指针
    spinlock_t file_lock;         // 文件表的自旋锁
    unsigned int next_fd;         // 下一个可用的文件描述符
    unsigned long close_on_exec;  // 需要在执行新程序时关闭的文件描述符标志
    unsigned long open_fds;        // 已打开文件描述符的位图
    struct file *fd_array[0];     // 指向打开文件的指针数组
};
  • fdt:指向 struct fdtable 的指针,表示文件描述符表。fdtable 包含了打开文件的数组以及相应的控制信息。
  • next_fd:表示下一个可用的文件描述符。在进程打开新文件时,会从这个位置开始分配文件描述符。
  • close_on_exec 和 open_fds:用于标记在执行新程序时需要关闭的文件描述符。
  • fd_array:这是一个指针数组,指向打开文件的指针

进程关联的文件系统状态

struct fs_struct {
    int users;                     // 引用计数
    spinlock_t lock;                // 用于保护结构的自旋锁
    struct path root;               // 进程的根目录
    struct path pwd;                // 进程的当前工作目录
    struct fdtable *files;          // 文件描述符表
    // 其他字段和操作省略...
};

它包含了与进程关联的文件系统状态,包括当前工作目录、根目录、以及与文件描述符表相关的信息。

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

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

相关文章

【ES数据可视化】kibana实现数据大屏

目录 1.概述 2.绘制数据大屏 2.1.准备数据 2.2.绘制大屏 3.嵌入项目中 1.概述 再来重新认识一下kibana: Kibana 是一个用于数据可视化和分析的开源工具,是 Elastic Stack(以前称为 ELK Stack)中的一部分,由 Ela…

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户 效果获取权限NotFoundErrorNotAllowedError 代码 效果 获取权限 NotFoundError NotAllowedError 代码 // 调用 captureLocalMedia()// 方法 function captureLocalMedia() {console.warn(Requesting lo…

C# CAD交互界面-自定义面板集(四)

运行环境 vs2022 c# cad2016 调试成功 一、引用 using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Windows; using System.Windows.Forms; 二、程序说明 创建自定义面板集(PaletteSet)的C#命令方法实现。该方法名为CreatePalette&#xff…

67-关于mysql-8.0连接SSL账号的一些问题

背景 近期开发反馈有个账号连不上数据库,问什么时候发现连不上的,开发说今天才开始用,好家伙,环境给到开发一个月了,现在才开始使用,申请的时候说急急急,明天就要上线。那咱们看看为啥这个账号…

step导入到solidworks外观处理方法

在导入到solidworks中的kuka机器人会变成灰色。看上去很不好看。如何才能大体恢复一下原外观呢?主要可以使用如下两种方法。 主要是使用了将里面的形状单独变成零件,方便装配,使机器人可以变化姿态。造成外观颜色丢失。 1.外观复制 如下图所…

人工智能|推荐系统——基于tensorflow的个性化电影推荐系统实战(有前端)

代码下载: 基于tensorflow的个性化电影推荐系统实战(有前端).zip资源-CSDN文库 项目简介: dl_re_web : Web 项目的文件夹re_sys: Web app model:百度云下载之后,把model放到该文件夹下recommend: 网络模型相…

大华 DSS 数字监控系统 attachment_getAttList.action SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS存在SQL注入漏洞,攻击者 /portal/attachment_getAttList.action 路由发送特殊构造的数据包,利用报错注入获…

事件的力量:探索Spring框架中的事件处理机制

欢迎来到我的博客,代码的世界里,每一行都是一个故事 事件的力量:探索Spring框架中的事件处理机制 前言什么是spring事件事件发布与监听自定义事件异步事件处理事件传播条件事件监听 前言 在现代应用程序中,各个组件之间的通信是至…

储氢材料行业调研:市场需求将不断增长

近年来,热度持续升温的碳中和、碳达峰话题,使得氢能及其相关产业被高度关注,而决定氢能应用关键的是安全、高效的氢能储运技术。在氢能需求不断增长的情况下,储氢材料行业是市场也将不断发展。在氢能需求不断增长的情况下,储氢材料…

《Python 网络爬虫简易速速上手小册》第4章:Python 网络爬虫数据抓取技术(2024 最新版)

文章目录 4.1 解析 HTML 与 CSS4.1.1 重点基础知识讲解4.1.2 重点案例:使用 BeautifulSoup 解析博客文章4.1.3 拓展案例 1:使用 lxml 和 XPath 解析产品信息4.1.4 拓展案例 2:动态加载内容的抓取挑战 4.2 动态内容抓取技术4.2.1 重点基础知识…

【C++】内存管理深入解析

目录 1. 内存的五大区域1.1 栈区(Stack)1.2 堆区(Heap)1.3 全局/静态存储区1.4 常量存储区1.5 代码区 2. 回顾c语言的动态内存管理2.1 malloc/calloc/realloc2.2 free 3. C中的新旧对话3.1 new3.2 delete 4. new/delete的实现原理…

ES6 ~ ES11 学习笔记

课程地址 ES6 let let 不能重复声明变量(var 可以) let a; let b, c, d; let e 100; let f 521, g "atguigu", h [];let 具有块级作用域,内层变量外层无法访问 let 不存在变量提升(运行前收集变量和函数&#…

ZigBee学习——在官方例程上实现串口通信

Z-Stack版本为3.0.2 IAR版本为10.10.1 文章目录 一、添加头文件二、定义接收缓冲区三、编写Uart初始化函数四、编写串口回调函数五、函数声明六、函数调用七、可能遇到的问题(function “halUartInit“ has no prototype) 以下所有操作都是在APP层进行,也就是这个文…

[Python 安装]

进入Python的官方下载页面 http://www.python.org/download/ 然后进行软件的下载 下载好之后点击exe会出现安装界面,接着进行安装,选择安装路径。 运行Python 安装成功后,打开命令提示符窗口(winR,在输入cmd回车&#xf…

C程序训练:二分查找法的应用之2

本文来自:C程序训练:二分查找法的应用之2 在《C程序训练:二分查找法的应用》一文中介绍了利用二分查找计算某个区间中数的个数,本文介绍利用二分查找法计算数列中出现单个数字的位置。题目描述如下。 题目描述:一维整…

Python进阶--下载想要的格言(基于格言网的Python爬虫程序)

注:由于上篇帖子(Python进阶--爬取下载人生格言(基于格言网的Python3爬虫)-CSDN博客)篇幅长度的限制,此篇帖子对上篇做一个拓展延伸。 目录 一、爬取格言网中想要内容的url 1、找到想要的内容 2、抓包分析,找到想…

Netty源码系列 之 bind绑定流程 源码

Netty框架总览 Netty是一个基于NIO异步通信框架 Netty框架是由许多组件,优化的数据结构所构建成。 正是通过灵活的组件构建,优化后的数据结构,进而才能保证Netty框架面对高并发场景具有一定的能力 Netty相关组件 Netty重要的组件有&…

代码随想录算法训练营DAY14 | 二叉树 (1)

一、二叉树理论基础 1.存储方式 链式存储: 顺序存储: 2.二叉树标准定义(Java) public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {…

spring cloud stream

背景 主要解决不同消息中间件切换问题。实现不同中间件的代码解耦。 链接: 支持的中间件 后文使用kafka测试。 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></depende…

微服务介绍、使用 Nacos 实现远程调用以及 OpenFeign 的使用

1 微服务的概念 区别于单体项目 单体项目拆分成微服务项目的目标&#xff1a;高内聚、低耦合 拆分思路 纵向拆分&#xff1a;根据功能模块 横向拆分&#xff1a;抽取可复用模块 2 微服务拆分——远程调用 背景&#xff1a;微服务单一职责&#xff0c;每个服务只有自己的功能…