Linux文件系统【真的很详细】

news2024/11/27 9:40:20

目录

 一.认识磁盘

1.1磁盘的物理结构

1.2磁盘的存储结构

1.3磁盘的逻辑存储结构

二.理解文件系统 

2.1如何管理磁盘

2.2如何在磁盘中找到文件 

2.3关于文件名


哈喽,大家好。今天我们学习文件系统,我们之前在Linux基础IO中研究的是进程和被打开文件之间的关系,以及如何管理被打开的文件。那么,在磁盘中没有被打开的文件应该怎样管理呢?今天,我们一块研究一下。我们开始啦!

 一.认识磁盘

磁盘作为硬件中的唯一一个机械结构,在计算机系统中的地位不言而喻,所以,我们有必要好好了解一下我们的磁盘。

1.1磁盘的物理结构

  • 随着计算机的更新换代,我们现在的笔记本上很少见到磁盘了。取自换代的是固态硬盘(ssd)。所以固态硬盘也要相对贵一些。磁盘作为一个机械结构,并且是外设,这就决定了访问磁盘的速度是很慢的(相对于CPU或者内存)。
  • 在企业中,磁盘依旧是存储的主流。因为:1.固态硬盘比较贵,磁盘相对来说比较便宜。2.磁盘的存储容量比较大,适合海量数据的存储。3.ssd有一个巨大的缺点:ssd如果传输次数过多,就会出现被击穿的情况,造成数据丢失;在企业中,高并发的情况非常常见,所以极其不适合在企业中使用。

磁盘是由很多盘片叠加在一起的。 一个盘片有两个盘面,每个盘面都可以读取数据,每个盘面都有磁头,盘片数=磁头数=盘面数*2

1.2磁盘的存储结构

在宏观的世界里,看起来盘面很光滑,但是在显微镜下,盘面是很粗糙的。

下面,先给大家介绍几个概念

  • 在一个盘面中,以中间的马达为圆心,会存在很多的同心圆,这些同心圆叫做磁道。磁头在旋转的过程就是确认在哪一个磁道的过程。
  • 磁盘中每一个磁道被等分为若干个相同的弧段,这些弧段便是磁盘的扇区,扇区是磁盘寻址的最小的单位。扇区的大小都是512字节。虽然距离圆心越远,扇区的长度越大,但是,我们可以使用存储的密度加以控制。使其存储的数据量相同,便于管理。盘片在旋转的过程就是确认在哪一个扇区的过程。
  • 为了方便管理,我们可以对不同的磁道进行编号,然后在同一磁道下对不同扇区再进行编号。

每个盘面对应一个磁头。所有的磁头都是连在同一个磁臂上的,因此所有磁头只能“共进退”。

所有盘面中相对位置相同的磁道组成柱面。如上图,柱面的存在使得更为方便的找到每一块扇区。

如何在多块磁片中,定位到一块扇区呢?

 先定位在哪一个磁盘(cylinder),也就是柱面(Track),再定位在哪一个盘面(head),最后定位扇区(sector)。我们可以定位任何一个扇区,也就可以定位任意多个扇区。

 磁盘中定义一个扇区,采用硬件的方式:CHS定位法。

1.3磁盘的逻辑存储结构

大家有没有见过磁带:

等待一盘磁带不用了,我们总是把里面黑色的磁带给扯出来,然后玩!磁带卷起来是圆形的(也是由很多同心圆构成的),扯出来是线性的。我们再看我们的磁盘,怎么和磁带这么相似呢?我们可以把整个磁盘全部抽象给一个线性结构。

磁盘物理上是一种圆形结构,我们可以想象成线性结构!如图:假设一块磁盘由2块盘片组成,所以就有4个盘面,一个盘面由7条磁盘构成,一个磁道又分成了8个沙区

就这样,我们把磁盘从逻辑上看做一个sector arr[4*7*8]的数组,所以由原来的对磁盘的管理变成了对数组的管理,这不就是我们常提到的先描述,再组织嘛!!

现在,这该死的磁盘已经被我们给想象成了一个数组,要找到一个扇区,该怎么找呢? 

只要知道这个扇区的下标,就算定位了一个扇区。在操作系统内部,我们称这个下标为LBA地址(逻辑块地址)。


现在有一块磁盘,相关数据如下:问:LBA地址为123的扇区位置?

为什么OS要对存储结构做逻辑抽象呢?直接用CHS不可以吗?

  • 便于管理。
  • 不想让代码和硬件强耦合。 

虽然磁盘访问的最小单位是512字节,但是依旧很小!OS内的文件系统定制的进行多个扇区的读取(一次读取4KB的数据)哪怕只想读取一个比特位,必须将4KBload到内存,进行读取或者读取。如果有必要再写回磁盘。这是一种以空间换时间的方式。

但这样,有时会显得非常浪费,比如我要读取的数据只有几个字节的大小,OS也要给我们一次性的读取4KB的数据。但这背后有一个原理叫做:局部性原理:从理论上证明了计算机要访问一段数据时,这段数据周围的数据也有较大的可能性被访问到。所以,真实的内存是以4KB为单位被操作系统读取的。磁盘中的文件(尤其是可执行文件),按4KB大小划分好的区域。

二.理解文件系统 

2.1如何管理磁盘

假设一个磁盘为500GB。操作系统说:“卧槽,这么大,怎么管呀?”。 虽然难管,但是这点问题难不住我们的工程师。他们将整个磁盘分区,每个区分出100GB甚至更小的空间,然后对每个区进行分组,每组分出5GB的空间,就这样分下去,直到方便管理为止。虽然5GB的空间很小了,但是对于500GB来说这就是小巫见大巫。这种思想叫做分治思想。一个5GB的空间管理好了,然后对刮管理方法进行复制,不就管理好整个磁盘了嘛 !。

就像我们同学在学校一样:一位同学,必定属于哪一个宿舍,这件宿舍必定属于哪一个班级,这个班级必定是属于哪一个专业,这个专业必定是属于哪一个学院,这个学院一定属于学校。这不就是在利用分治思想来进行管理嘛!

 

 

文件=内容+属性,Linux下的内容和属性是分批存储的,但是一个未打开的文件的内容和属性信息都存储在哪里呢?

  • 文件属性存储在Inode中,Inode是固定大小,一个人文件,一个Inode。一个文件的所有属性几乎都存储在Inode中,但是文件名并不存储在Inode中。
  • 文件的内容存储在data  block数据块中,数据块随着应用类型的变化,大小也会发生变化。

关于Inode属性集合

  • 由于每个文件都有Inode,为了区分彼此,每个Inode都有自己的编号。编号是以组为单位进行编的。

那么,在Linux下,如何查看文件的inode编号呢?

 

 inode table:

保存分组内部所有可用的(已经使用+没有使用)的inode。

Data blocks:

 保存分组内部所有可用的(已经使用+没有使用)的数据快。

如果我们要创建一个文件,怎么办?

  1. 查找没有使用的Inode,然后把属性写入Inode中。
  2. 查找没有使用的数据块,然后把内容写入数据块。

所以,我们创建文件的过程,离不开查找。如何查找呢?

 Inode Bitmap:

Inode对应的位图结构。假设inode一共有n个,位图结构中的比特位的个数至少也为n个。

位图中比特位的位置与当前文件的对应的ID是一一对应的,比特位的1和0表示是否被占用。 

block Bitmap:

数据块对应的位图结构。位图中比特位的位置和当前data block对应的数据块的位置是一一对应的。 

 如果要知道inode一共有多少个,没有使用的是多少个,如果通过计算获取结果,效率太低了,这时Group Descriptor Table出现了。

Group Descriptor Table:

包含对应分组的宏观属性信息,包括:一共有多少个数据块,使用了多少;一共有多少个Inode,使用了多少等等。 

Super Block
超级块(Super Block):存放文件系统本身的结构信息。
  记录的信息主要有:bolck 和 inode 的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。

  并且超级块通常在分组内多个组有一个超级块,在系统中是有一定比例的,假设我一个100G的分区有1000个分组,每20个分组就有一个super block,那么总共就有50个超级块。为什么需要这些超级块呢?本质上还是为了数据备份,如果某个块组或者inode丢失,那么就 可以通过super block来进行恢复。

2.2如何在磁盘中找到文件 

 查找一个文件,要通过Inode编号。

  • 通过inode bitmap 查找对应的比特位的位置是1还是0
  • 如果这个编号被占用,在inode Table找到这个Inode,然后确定一下是否是我们要查找的文件。

但是,如果我要得到这个文件的内容呢?

inode在内核中的结构如下:

struct inode {
    umode_t         i_mode;//文件的访问权限(eg:rwxrwxrwx)
    unsigned short      i_opflags;
    kuid_t          i_uid;//inode拥有者id
    kgid_t          i_gid;//inode拥有者组id
    unsigned int        i_flags;//inode标志,可以是S_SYNC,S_NOATIME,S_DIRSYNC等

#ifdef CONFIG_FS_POSIX_ACL
    struct posix_acl    *i_acl;
    struct posix_acl    *i_default_acl;
#endif

    const struct inode_operations   *i_op;//inode操作
    struct super_block  *i_sb;//所属的超级快
    /*
        address_space并不代表某个地址空间,而是用于描述页高速缓存中的页面的一个文件对应一个address_space,一个address_space与一个偏移量能够确定一个一个也高速缓存中的页面。i_mapping通常指向i_data,不过两者是有区别的,i_mapping表示应该向谁请求页面,i_data表示被改inode读写的页面。
    */
    struct address_space    *i_mapping;

#ifdef CONFIG_SECURITY
    void            *i_security;
#endif

    /* Stat data, not accessed from path walking */
    unsigned long       i_ino;//inode号
    /*
     * Filesystems may only read i_nlink directly.  They shall use the
     * following functions for modification:
     *
     *    (set|clear|inc|drop)_nlink
     *    inode_(inc|dec)_link_count
     */
    union {
        const unsigned int i_nlink;//硬链接个数
        unsigned int __i_nlink;
    };
    dev_t           i_rdev;//如果inode代表设备,i_rdev表示该设备的设备号
    loff_t          i_size;//文件大小
    struct timespec     i_atime;//最近一次访问文件的时间
    struct timespec     i_mtime;//最近一次修改文件的时间
    struct timespec     i_ctime;//最近一次修改inode的时间
    spinlock_t      i_lock; /* i_blocks, i_bytes, maybe i_size */
    unsigned short          i_bytes;//文件中位于最后一个块的字节数
    unsigned int        i_blkbits;//以bit为单位的块的大小
    blkcnt_t        i_blocks;//文件使用块的数目

#ifdef __NEED_I_SIZE_ORDERED
    seqcount_t      i_size_seqcount;//对i_size进行串行计数
#endif

    /* Misc */
    unsigned long       i_state;//inode状态,可以是I_NEW,I_LOCK,I_FREEING等
    struct mutex        i_mutex;//保护inode的互斥锁

    //inode第一次为脏的时间 以jiffies为单位
    unsigned long       dirtied_when;   /* jiffies of first dirtying */

    struct hlist_node   i_hash;//散列表
    struct list_head    i_wb_list;  /* backing dev IO list */
    struct list_head    i_lru;      /* inode LRU list */
    struct list_head    i_sb_list;//超级块链表
    union {
        struct hlist_head   i_dentry;//所有引用该inode的目录项形成的链表
        struct rcu_head     i_rcu;
    };
    u64         i_version;//版本号 inode每次修改后递增
    atomic_t        i_count;//引用计数
    atomic_t        i_dio_count;
    atomic_t        i_writecount;//记录有多少个进程以可写的方式打开此文件
    const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
    struct file_lock    *i_flock;//文件锁链表
    struct address_space    i_data;
#ifdef CONFIG_QUOTA
    struct dquot        *i_dquot[MAXQUOTAS];//inode磁盘限额
#endif
    /*
        公用同一个驱动的设备形成链表,比如字符设备,在open时,会根据i_rdev字段查找相应的驱动程序,并使i_cdev字段指向找到的cdev,然后inode添加到struct cdev中的list字段形成的链表中
    */
    struct list_head    i_devices;,
    union {
        struct pipe_inode_info  *i_pipe;//如果文件是一个管道则使用i_pipe
        struct block_device *i_bdev;//如果文件是一个块设备则使用i_bdev
        struct cdev     *i_cdev;//如果文件是一个字符设备这使用i_cdev
    };

    __u32           i_generation;

#ifdef CONFIG_FSNOTIFY
   //目录通知事件掩码
    __u32           i_fsnotify_mask; /* all events this inode cares about */
    struct hlist_head   i_fsnotify_marks;
#endif

#ifdef CONFIG_IMA
    atomic_t        i_readcount; /* struct files open RO */
#endif
    //存储文件系统或者设备的私有信息
    void            *i_private; /* fs or device private pointer */
};

其中,有一个关于数组块的数组,data block block[15]。

 

这个数组元素的个数是固定的。但并表示这个文件可以写入的数据量是一定的。如图:每一个数据块都有自己的编号,这个数组中存放的就是该文件所使用的数据块的编号,通过这个数组就可以实现我们查找内容的行为。虽然只有15元素,但并不代表我们仅可以使用15个数据块。从下表为12的元素开始,所指向的数据块里边保存的是其他数据块的编号,下一级数据块中的内容可以使下下一级数据块的编号。如此,就可以增加我们可使用数据块的个数。为了便于大家理解,做如下图:

所以,我们就顺利完成了文件的查找工作,那么,如何删除一个文件呢? 

删除文件就太简单了,只需要找到这个文件,然后将这个文件的Inode编号对应的比特位由1置为0就可以了。然后将block bitmap由1置为0就可以了。(惰性删除)

这里并没有直接删除数据块,所以Linux下删除是可以恢复的。

2.3关于文件名

这是什么鬼?我们不是说可以根据inode编号查找文件嘛,这里为什么不可以使用编号查找呀 ?

我们说:Linux下一切皆是文件。其实,目录本身就是一个文件,文件的属性容易理解,但是,文件的内容是什么呢?

目录文件的内容就是编号和文件名之间的映射关系,所以,我们之前提到再inode中不需要存储文件名。记录文件名是目录的事情。

 写到最后,因水平有限,文中难免会出现错误,请各位大佬指正!!

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

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

相关文章

将Jar用三种方式生成Windows的安装程序

无论是WEB(spring boot)的JAR,还是JavaFX以及swing的Jar,要生成windows方式。 打包成Windows可执行文件(.exe),你可以使用以下三种方法: ### 方法1:使用Inno Setup 1. **构建JavaFX应用程序**: 使用M…

自制一个Linux live固件镜像ISO可引导系统

使用母盘镜像制作两个虚拟,来制作一个包含基本需求的filesystem.squashfs文件,具体看下面的链接 使用的安装镜像 是Linux Mint 制作好的成品 https://cloud.189.cn/t/U32Mvi7FnyA3 (访问码:2nbo) 最简单制作LIVE CD…

ChatGPT魔法背后的原理:如何做到词语接龙式输出?

介绍 我们都知道 ChatGPT 是 AIGC 工具,其实就是生成式人工智能。大家有没有想过这些问题 🤔️: 1、我们输入一段话,就可以看见它*噼里啪啦的一顿输出*,那么它的原理到底是什么? 2、到底它是怎么锁定这些…

【Prometheus】Prometheus的k8s部署

Kubernetes 集群部署 Prometheus 和 Grafana //实验环境 控制节点/master01 192.168.67.30 工作节点/node01 192.168.67.12 工作节点/node02 192.168.67.13 //node-exporter 安装 #创建监控 namespace kubectl create ns monitor-sa #部署 nod…

Java—装饰器模式

介绍 装饰器模式 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。 主要角色 Component:定义一个对…

【数据的增值之路】全生命周期的数据演化过程

引言:随着云计算、大数据、人工智能、区块链等新一代信息技术的快速发展,数据已经成为推动经济增长的重要生产要素。数据量的爆炸式增长,为挖掘数据价值、推动数字经济发展提供了丰富的资源基础。重要概念解析: 数据经济&#xf…

[图解]建模相关的基础知识-09

1 00:00:01,350 --> 00:00:03,780 首先,我们来看一下什么叫关系 2 00:00:05,370 --> 00:00:08,990 这个关系跟下面说的这些关系 3 00:00:09,000 --> 00:00:10,390 它不是一个东西 4 00:00:11,110 --> 00:00:14,950 比如说,我们UML类图上&…

【因果推断python】36_断点回归2

目录 RDD 估计 内核加权 RDD 估计 RDD 依赖的关键假设是阈值处潜在结果的平滑性。用比较正式地表述来说,当运行变量从右侧和左侧接近阈值时,潜在结果的极限应该是相同的。 如果这是真的,我们可以在阈值处找到因果关系 从其本身意义来说&…

RocketMQ源码学习笔记:源码启动NameServer,Broker

这是本人学习的总结,主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview2、NameServer2.1、源码启动NameServer 3、Broker启动过程 1、Overview 这篇文章的源码的版本是release-4.9.8。在启动各个模块之前应该先对项目进行打包mvn install -Dmaven.te…

大数据实训项目(小麦种子)-04、大数据实训项目JavaWeb环境搭建

文章目录 前言运行前准备工作1、安装Hadoop3.1.0配置winutils原因描述配置方式注意点(hadoop.dll拷贝System32目录下) 2、hive运行报错(The dir: /tmp/hive on HDFS should be writable. ) 项目环境搭建参考资料 前言 博主介绍&a…

【类脑计算】突触可塑性模型之Hebbian学习规则和STDP

1 引言 突触可塑性 (Synaptic plasticity)指经验能够修改神经回路功能的能力。特指基于活动修改突触传递强度的能力,是大脑适应新信息的主要调查机制。分为短期和长期突触可塑性,分别作用于不同时间尺度,对感官刺激的短期适应和长期行为改变…

unity数独游戏

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class MainMenuPanel : MonoBehaviour {public Button btnPlay; // 开始按钮public Slider sldDifficulty; // 难度滑动条private void Awake(){/…

省去烦恼!轻松实现一台电脑登录多个微信号的秘诀揭秘!

你知道如何在同一台电脑上登录多个微信号,并实现聚合聊天吗? 今天,我将分享一个多微管理神器——个微管理系统,帮助你解决这一问题! 1、多号同时登录,聚合聊天 无论你有多少个微信号,都可以一…

畅想智能美颜工具的未来:美颜SDK技术详解

美颜SDK作为技术的核心,承载了美颜工具的实现和创新。本篇文章,小编将深入探讨美颜SDK技术的细节。 一、技术原理 美颜SDK是一种软件开发工具包,集成了一系列图像处理算法和技术,旨在实现对照片和视频中人物的实时美化。其主要技…

Hyper-V如何将文件复制到虚拟机?教您3个简单的方法!

需要将文件复制到虚拟机! “大家好,有谁知道Hyper-V怎么将文件复制到虚拟机吗?我有一些文件,想要从主机中复制进虚拟机中,但是我不知道该怎么操作,有谁可以帮帮我吗?谢谢。” Hyper-V虚拟机可…

家庭海外仓:优势,挑战以及如何利用海外仓系统提升效率

家庭海外仓凭借其灵活,服务优良的特点,一直受到很多跨境电商企业的欢迎,不过,在当今的市场竞争之下,家庭海外仓也同样面临一些挑战,今天我们就来系统的分析一下家庭海外仓应该如何通过海外仓系统的引入来解…

Web期末复习指南(2w字总结)

前言:本文旨在梳理Web技术常包含的内容,阅读完整篇文章后会对整体有个系统的认知,从前端的HTML到后端的MySql,对于大概试题中可能会涉及的地方都有所分析,通篇提供了许多代码案例,供读者更好的理解。对于一…

Oracle阅读Java帮助文档

进入到Help Center 选择Java 查看Java SE [version]对应版本相关的内容 查看其它版本 查看Java11 javac等相关参数 目录查看java相关命令

能耗分析与远程抄表是什么?

一、引言 在21世纪的数字化时代,能耗分析和远程抄表已成为现代能源管理的重要组成部分。这两项技术不仅提高了能源效率,还为企业和个人提供了更精细的能源使用数据,从而实现更科学的节能减排。 二、能耗分析的深度洞察 能耗分析是通过收集…

一文带你搞清楚AI领域的高频术语!RAG、Agent、知识库、向量数据库、知识图谱、Prompt...都是在讲啥?

随着AI人工智能技术的不断发展,一些领域有关的概念和缩写总是出现在各种文章里,像是Prompt Engineering、Agent 智能体、知识库、向量数据库、RAG 以及知识图谱等等,但是这些技术和概念也的的确确在AI大模型的发展中扮演着至关重要的角色。这…