• 【Linux】C文件系统详解(四)——磁盘的物理和抽象结构


    磁盘结构

    磁盘物理结构

    磁盘是计算机上唯一的一个机械设备,同时还是外设->非常慢(相对于cpu/内存)
    磁头和盘面是没有挨着的,但是距离依旧很近:好比波音747距离地面一米飞行

    对数据做写入和读取:更改基本元素的南北磁极
    ![[基础IO 2023-11-17 10.43.58.excalidraw|900]]

    ![[Pasted image 20230325115202.png]]

    向磁盘写入:N->S
    删除磁盘数据:S->N
    所以一旦摩擦生热,就会消磁,数据就会丢失了

    磁盘的具体物理结构

    尝试在硬件上,理解数据的一次读和写
    ![[基础IO 2023-11-17 11.03.04.excalidraw|900]]

    磁盘中存储的基本单元:扇区,一般是512字节(4096个比特位),也有4kb字节的
    一般磁盘,所有的扇区,都是512字节
    半径相同的所有扇区,构成一圈"磁道"(多个面的相同磁道形成一个柱面)
    在一面上,如何在硬件上定位一个扇区呢?
    首先定位哪一个面:只需要确定用哪一个磁头读取,磁头的编号表示的就是哪一个面
    然后:

    1. 先定位在哪一个磁道->由半径决定
    2. 再确定在该磁道的哪一个扇区->根据扇区的编号来定位一个扇区

    磁头 head->柱面(磁道) cylinder->扇区 sector
    CHS定位法

    而一个普通文件(属性+数据) ->都是数据(0/1) -> 无非就是占用一个或者多个扇区,来进行自己的数据存储的.
    我们既然能够用CHS定位任意一个扇区,我们就肯定能定位多个扇区,从而将文件从硬件角度,进行读取或者写入

    磁盘结构的逻辑抽象

    根据以上内容,如果OS能够得知任意一个CHS地址,就能访问任意一个扇区
    但是OS内部不是直接使用的CHS地址
    为什么?

    1. OS是软件,硬件定位一个地址是用得CHS,但是,如果OS直接用了这个地址,万一硬件变了,OS也要发生变化.OS要和硬件做好解耦工作
    2. 即便是扇区,512字节,单位IO的基本数据量也是很小的,硬件是按照512字节处理,OS实际进行IO,基本单位是4KB(可以调整->通过编译linux源代码),因此我们把磁盘叫做块设备. 所以OS需要一套新的地址来进行块级别的访问

    我们将圆形的磁盘盘面想象为一个线性结构:
    ![[基础IO 2023-11-17 21.12.02.excalidraw|900]]

    可是我们磁盘只认CHS
    所以我们需要让LBA和CHS互相转换

    通过简单的数学运算就可以做到:
    伪代码:
    假设两个面,每个面5000个扇区,每个磁道500扇区
    LBA:6500
    C:6500/1000 = 6 (6号磁道)
    H:int n = 6500/5000 = 1 (所以在第二面)
    S:6500%1000 = 500(第500扇区)
    连续读取8个扇区,我们就能得到块了

    OS要管理磁盘,就将磁盘看作一个大数组,所以对磁盘的管理,就变成了对数组的管理

    先描述,再组织!!!

    文件系统

    ![[基础IO 2023-11-17 21.40.52.excalidraw|900]]

    接下来我们谈的都是一个分区:(分区就类似与win的"分盘: C盘,D盘…")
    ![[Pasted Image 20231117214219_277.png]]

    文件 = 内容 + 属性

    最终都要以块的形式,保存在磁盘的某个位置
    Linux是将内容和属性分离的

    BootBlock

    与系统的开机有关

    SuperBlock

    文件系统的所有属性信息

    1. 文件系统的类型
    2. 整个分组的情况
      为什么每个分组都可能有SB,而且是统一更新的:

    是为了防止SB区域坏掉,如果出现故障,整个分区就不可以被使用了,所以要做好备份
    (多副本保证分区安全)

    GroupDescriptorTable

    GDT -> 组描述符–改组内的详细统计等属性信息

    inode table

    一般而言,一个文件内部所有属性的集合,我们称之为inode节点(128字节),一个文件,有一个inode
    即便是一个分区,内部也会存在大量的inode节点
    一个group需要有一个区域来专门保存该group内所有文件的inode节点–>inode table
    分组内部可能会存在多个inode,所以需要将inode区分开来,每一个inode都会有自己的inode编号
    inode编号也属于对应文件的属性id

    DataBlocks

    一个文件的内容是变化的,我们是用数据块来进行文件内容的保存的,所以一个有效文件,要保存内容,就需要[1,n]个数据块
    如果有多个文件,就需要更多的数据块,DataBlocks
    Linux查找一个文件,首先是要根据inode编号,来进行文件查找,包括读取内容

    struct inode
    {
    	int number;
    	//...
    	int blocks[NUM];//先简单理解,对应的就是该文件对应的数据块的编号
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    所以一个inode对应一个文件,该文件inode属性和该文件blocks内容(数据块->4kb)是有映射关系的

    inodeBitmap

    inode bitmap的每一个bit表示inode是否空闲可用
    4kb(一个块):4096*8 = 32768(比特位)
    1表示inode正常工作,0表示inode不正常工作

    blockBitmap

    block bitmap的每一个bit表示datablock是否空闲可用

    ls -il//显示文件的inode编号
    
    • 1

    linux中的inode 和文件名

    linux系统只认inode号,inode属性中文件,并不存在文件名!
    文件名是给用户用的
    ->重新认识目录:

    1. 目录是文件吗–是
    2. 目录有inode以及内容吗–有
    3. 任何一个文件,一定是在一个目录内部,所以目录的内容是什么呢?数据块,目录的数据块里面保存的是该目录下文件名和文件inode编号对应的映射关系,在目录内,文件名和inode互为key值
    4. 当我们访问一个文件的时候,我们是在特定目录下访问的,基本流程是:
      1. cat log.txt 先要在当前目录下,找到对应的inode编号
      2. 一个目录也是一个文件,一定隶属于一个分区,结合inode,在该分区中找到分组,在该分组中inodetable中找到inode
      3. 通过inode和对应的datablock关系找到对应的数据块,并加载到OS,并显示到显示器

    如何理解文件的增删查改

    常识:删除数据比拷贝数据快多了
    做法:

    1. 根据文件名->inode number
    2. inode number -> inode属性中的映射关系,设置block bitmap 对应的比特位置0
    3. inode number 设置inode bitmap 对应的比特位为0
      删文件只需要修改位图即可

    补充细节

    1.如果文件误删了,我们该怎么办?

    正确的做法:什么都不要干,使用某种软件找到这个文件的inode编号,首先在分组中对应的inodebitmap对应位置置为1,再查找inode表对应的数据块bitmap置为1,然后查找数据块,就能恢复出来了

    2.inode确定分组,inode number是在一个分区内有效,不能跨分区

    举个例子,一个分区内,有100个分组,每个分组有100个inode编号,当inode是250号的时候,我们就能推算出他是在第三组的

    3.上面我们学到的分区,分组,填写系统属性->谁做的呢?什么时候做的呢

    是操作系统做的,是在分区完成之后,后面要让分区能够正常使用,我们要用格式化
    格式化的过程,其实是OS向分区写入文件系统的管理属性信息

    冷门知识:
    大型公司更换磁盘,其中的磁盘不能随意流向市场,必须被销毁

    4.我们如果inode只是单单地用数组和datablock的映射关系

    假设inode里的数组大小是15*4kb,是不是意味着一个文件内容最多放入60kb呢

    struct inode
    {
    	int inode number;
    	int ref_count;
    	mode_t mode;
    	int uid;
    	int gid;
    	int size;
    	data;
    	//...
    	block datablock[NUM];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ![[基础IO 2023-03-25 17.15.44.excalidraw|900]]

    5.有没有可能一个分区,数据块没用完,inode没了,或者inode没用完,datablock用完了

    有可能
    这样确实可能会存在资源浪费,但是没什么大影响

  • 相关阅读:
    win11,无法修改文件的只读属性,解决办法
    git diff,stash,submodule,format-patch
    《canvas》之第9章 渐变与阴影
    prototype-based learning algorithm(原型学习)
    DelayQueue 使用和延时功能源码分析
    draggable实现拖拽、禁止拖拽、拖拽后元素重新排序到指定位置
    SAR数据的多视Multi-look,包括range looks和azimuth looks,如何设置多视比
    利用Python将dataframe格式的所有列的数据类型转换为分类数据类型
    UE4 C++ 笔记(二):基础知识
    B. Two-gram
  • 原文地址:https://blog.csdn.net/weixin_62712120/article/details/134501446