Linux磁盘与文件系统原理

时间:2021-10-07 05:07:17

这一章主要是原理性的,介绍了Linux文件系统的运作原理。涉及到很多计算机组成和操作系统的原理性知识,这部分知识很多都忘了,在这里复习下。
    我们只看本章第1,2节。

---------------------------------------------------------------------------------------------------------------------------------------------------

1 硬盘物理组成     //原理

    磁头负责读写
    磁道(硬盘同半径的一圈) 磁柱(所有盘磁道叠加起来的柱)
    扇区(2条半径将磁道分开的一个扇形区域,是磁盘的最小存储单位)

---------------------------------------------------------------------------------------------------------------------------------------------------

2 磁盘分割    //原理

    磁柱是磁盘分割的最小单位
    磁盘分割就是指定一个分割(Partition)的是从A磁柱到B磁柱
    
    所有磁盘的分割信息存放在MBR(主要开机扇区,master boot recoder),即一块硬盘的第0轨上。计算机一开机就会去读取这个区域。
    由MBR的含义知,若一个硬盘的MBR挂了,这块硬盘就等于挂了。

    MBR的限制:MBR的大小决定了它不能存储很多的分割信息,最多只能记忆四个分割的信息(主分区和扩展分区都称为一个分割),而扩展分区最多只能有一个。
    由以上知识知,一块硬盘最多四个分割,且扩展分区只能有一个。举个例子,若你分割了3p+1E,那么你就不能再分割分区了。

---------------------------------------------------------------------------------------------------------------------------------------------------

3 档案系统(文件系统)    //原理

    在告知系统我的 partition 所在的起始与结束磁柱之后,再来则是需要将 partition 格式化为『我的操作系统认识的档案系统( Filesystem )』

    我们可以说,每一个 partition 就是一个 Filesystem。

    刚刚我们提到硬盘的最小储存单位是 sector ,不过数据所储存的最小单位并不是 sector ,因为用 sector 来储存太没有效率了。 为了克服这个效率上的困扰,所以就有逻辑区块( Block )的产生了! 逻辑区块是在 partition 进行 filesystem 的格式化时, 所指定的『最小储存单位』,这个最小储存单位当然是架构在 sector 的大小上面( 因为 sector 为硬盘的最小物理储存单位啊! ),所以 Block 的大小为 sector 的 2 的次方倍数。
    
    规划Block大小的考量:档案读取效率;档案大小可能造成的空间浪费

    Superblock:如同前面说的,当我们在进行磁盘分割( partition )时,每个磁盘分割槽( partition )就是一个档案系统( filesystem ), 而每个档案系统开始的位置的那个 block 就称为 superblock ,superblock 的作用是储存像是档案系统的大小、空的和填满的区块,以及他各自的总数和其它诸如此类的信息等等, 这也就是说,当您要使用这一个磁盘分割槽( 或者说是档案系统 )来进行数据存取的时候,第一个要经过的就是 superblock 这个区块了,所以啰, superblock 坏了,您的这个磁盘槽大概也就回天乏术了!

    注意啦,MBR和Superblock是两个层次上的东西!!!

    磁盘分割,档案系统的关系:在磁盘分割选择文件系统的格式时,此时格式化,就把某种格式的文件系统架构在磁盘之上了。

---------------------------------------------------------------------------------------------------------------------------------------------------

4 Linux的EX2档案系统    //原理

    Linux的档案不仅具有档案内容,还有档案属性。Linux文件系统将档案属性(存放在inode中)和档案内容(存放在block中)分开来存储。
    
    当一个partition被格式化为ext2文件系统时,就会有inode table和block area这两个区域,inode都在inode table这个区域,block在block area区域。
    
   Block 已经在前面说过了,他是数据储存的最小单位。那么 inode 是什么?!简单的说, Block 是记录『档案内容数据』的区域,至于 inode 则是记录『该档案的相关属性,以及档案内容放置在哪一个 Block 之内』的信息。 简单的说, inode 除了记录档案的属性外,同时还必须要具有指向( pointer )的功能,亦即指向档案内容放置的区块之中,好让操作系统可以正确的去取得档案的内容。
    
    Linux 系统到底是如何读取一个档案的内容呢?底下我们分别针对目录与档案来说明:

      目录: 当我们在 Linux 下的 ext2 档案系统建立一个目录时, ext2 会分配一个 inode 与至少一块 Block 给该目录。其中,inode 记录该目录的相关属性,并指向分配到的那块 Block ;而 Block 则是记录在这个目录下的相关连的档案(或目录)的关连性!
      档案: 当我们在 Linux 下的 ext2 建立一个一般档案时, ext2 会分配至少一个 inode 与相对于该档案大小的 Block 数量给该档案。例如:假设我的一个 Block 为 4 Kbytes ,而我要建立一个 100 KBytes 的档案,那么 linux 将分配一个 inode 与 25 个 Block 来储存该档案!

      要注意的是, inode 本身并不纪录文件名,而是记录档案的相关属性,至于文件名则是记录在目录所属的 block 区域! 那么档案与目录的关系又是如何呢?就如同上面的目录提到的,档案的相关连结会记录在目录的 block 数据区域, 所以当我们要读取一个档案的内容时,我们的 Linux 会先由根目录 / 取得该档案的上层目录所在 inode , 再由该目录所记录的档案关连性 (在该目录所属的 block 区域) 取得该档案的 inode , 最后在经由 inode 内提供的 block 指向,而取得最终的档案内容。我们以 /etc/crontab 这个档案的读取为例, 他的内容数据是这样取得的:

  

Linux磁盘与文件系统原理

另外,关于 EXT2 档案系统,这里有几点小事情要提醒一下:(理解一下)

  ? ext2 与 ext3 档案在建立时 (format) 就已经设定好固定的 inode 数与 block 数目了;

  ? ext2 允许的 block size 为 1024, 2048 及 4096 bytes;

  ? 一个 partition (filesystem) 所能容许的最大档案数,与 inode 的数量有关, 因为一个档案至少要占用一个 inode 啊!

  ? 在目录底下的档案数如果太多而导致一个 Block 无法容纳的下所有的关连性数据时,Linux 会给予该目录多一个 Block 来继续记录关连数据;

  ? 通常 inode 数量的多寡设定为 (partition 的容量) 除以 (一个 inode 预计想要控制的容量)。 举例来说,若我的 block 规划为 4Kbytes,假设我的一个 inode 会控制两个 block ,亦即是假设我的一个档案大致的容量在 8Kbytes 左右时,假设我的这个 partition 容量为 1GBytes, 则 inode 数量共有:( 1G * 1024M/G * 1024K/M ) / ( 8K ) = 131072 个。而一个 inode 占用 128 bytes 的空间,因此格式化时就会有 ( 131072个 * 128bytes/个 ) = 16777216 byes = 16384 Kbytes 的 inode table 。也就是说,这一个 1GB 的 partition 在还没有储存任何数据前, 就已经少了 16MBytes 的容量啊!

  ? 因为一个 inode 只能记录一个档案的属性,所以 inode 数量比 block 多是没有意义的! 举上面的例子来说,我的 Block 规划为 4 Kbytes ,所以 1GB 大概就有 262144 个 4Kbytes 的 block ,如果一个 block 对应一个 inode 的话,那么当我的 inode 数量大于 262144 时,多的 inode 将没有任何用处,徒然浪费硬盘的空间而已!另外一层想法,如果我的档案容量都很大, 那么一个档案占用一个 inode 以及数个 block ,当然 inode 数量就可以规划的少很多啦!

  ? 当 block 大小越小,而 inode 数量越多,则可利用的空间越多,但是大档案写入的效率较差; 这种情况适合档案数量多,但是档案容量小的系统,例如 BBS 或者是新闻群组( News )这方面服务的系统;

  ? 当 Block 大小越大,而 inode 数量越少时,大档案写入的效率较佳,但是可能浪费的硬盘空间较多; 这种状况则比较适合档案容量较大的系统!

---------------------------------------------------------------------------------------------------------------------------------------------------

5 Ex2文件系统的存储架构图及原理        //原理

    当一个 ext2 的 filesystem 被建立时, 他拥有 superblock / group description / block bitmap / inode bitmap / inode table / data blocks 等等区域。要注意的是,每个 ext2 filesystem 在被建立的时候,会依据 partition 的大小, 给予数个 block group ,而每个 block group 就有上述的这些部分。整个 filesystem 的架构可以下图展现:

      

Linux磁盘与文件系统原理

        我们将整个 filesystem 简单化, 假设仅有一个 block group ,那么上面的各个部分分别代表什么呢:

         ?SuperBlock:如前所述, Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有:

              o block 与 inode 的总量;
              o 未使用与已使用的 inode / block 数量;
              o 一个 block 与一个 inode 的大小;
              o filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等档案系统的相关信息;
              o 一个 valid bit 数值,若此档案系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。

        ? Group Description:纪录此 block 由由何处开始记录;

        ? Block bitmap:此处记录那个 block 有没有被使用;

        ? Inode bitmap:此处记录那个 inode 有没有被使用;

        ? Inode table:为每个 inode 数据存放区;

        ? Data Blocks:为每个 block 数据存放区。

    当我们新增一个档案(目录)时:

        1. 根据 inode bitmap / block bitmap 的信息,找到尚未被使用的 inode 与 block , 进而将档案的属性与数据分别记载进 inode 与 block ;
    
        2. 将刚刚被利用的 inode 与 block 的号码 (number) 告知 superblock、inode bitmap、block bitmap 等,让这些 metadata 更新信息。一般来说,我们将 inode table 与 block area 称为数据存放区域,至于其它的例如 superblock、 block bitmap 与 inode bitmap 等记录就被称为 metadata 啰。经由上面两个动作,我们知道一笔数据写入硬盘时, 会有这两个动作。

    

---------------------------------------------------------------------------------------------------------------------------------------------------

    
6 档案系统的运作    //原理

    好了,我们知道整个 ext2/ext3 的数据存取是透过 journal(日志) 与 metadata 还有数据存放区在纪录的。 不过,实际上, Linux 档案系统在运作的时候,真的要将数据直接存放到硬盘上面吗?!

      为了让 Linux 加快整个系统的存取效率,因此在 Linux 上面通常采取异步处理( asynchronously )的方式。 什么是异步呢?举例来说:『当系统读取了某一个档案, 则该档案所在的区块数据会被加载到内存当中,所以该磁盘区块就会被放置在主存储器的缓冲快取区中, 若这些区块的数据被改变时,刚开始数据仅有主存储器的区块数据会被改变, 而且在缓冲区当中的区块数据会被标记为『 Dirty 』,这个时候磁盘实体区块尚未被修正! 所以亦即表示,这些『 Dirty 』区块的数据必需回写到磁盘当中, 以维持磁盘实体区块上的数据与主存储器中的区块数据的一致性。』 

    为什么要这么做呢?这是因为主存储器的运作速度比起硬盘来实在是快太多了, 万一系统当中有一个档案相当的大,而又持续性的存取,那么由于较慢的硬盘存取速度,将使得整个 Linux 速度被拖垮,所以才会使用异步方式的数据处理啊!

    不过, 也由于硬盘与主存储器的数据可能没有同步化,因此,如果 Linux 不正常关机( 例如跳电或者是当机 )时,会导致系统在再次开机时,会花相当多的时间进行磁盘检验, 同时也有可能造成磁盘的损毁啊!

---------------------------------------------------------------------------------------------------------------------------------------------------

7 挂载点的意义        
    

    挂载点一定是『目录』而不是档案喔! 也就是说,这个挂载点就是进入该 filesystem 的入口。

---------------------------------------------------------------------------------------------------------------------------------------------------

8   磁盘与目录容量  // 实践
    
      1) 显示目前磁盘的总容量与剩余可用容量的指令
        
             df  [参数]    目录或文件名

                

Linux磁盘与文件系统原理

   2) 列出目录下各个档案所占的容量

            du    [参数]    目录或文件名
    

Linux磁盘与文件系统原理

---------------------------------------------------------------------------------------------------------------------------------------------------

9   连接档     

    1)    hard link

      Hard Link 只是在某个目录下新增一个该档案的关连数据而已!
 
      举个例子来说,假设我的 /root/crontab 为一个 hard link 的档案,他连结到 /etc/crontab 这个档案,也就是说,其实 /root/crontab 与 /etc/crontab 是同一个档案,只是有两个目录( /etc 与 /root )记录了 crontab 这个档案的关连数据罢了!也就是说,我由 /etc 这个目录所记录的关连数据可知道 crontab 的 inode 放置在 A 处,而由 /root 这个目录下的关连数据, crontab 同样也指到 A 处的 inode !所以啰, crontab 这个档案的 inode 与 block 都没有改变, 有的只是有两个目录记录了关连数据。 那这样有什么好处呢?最大的好处就是『安全!』如同上面提到的 /root/crontab 与 /etc/crontab 中, 不管哪一个档案被删除了,其实仅是移除一笔目录底下的档案关连性数据,并没有更动到原本档案的 inode 与 block 数据呢!而且,不论由那个目录连结到正确的 crontab 的 inode 与 block , 都可以正确无误的进行数据的修改喔! 

       一般来说,使用 hard link 设定连结文件时,磁盘的空间与 inode 的数目都不会改变! 由上面的说明来看,我们可以知道, hard link 只是在某个目录下的 block 多写入一个关连数据,所以当然不会用掉 inode 与磁盘空间啰!
    
      Tips: 其实可能会改变的,那就是当目录的 Block 被用完时,就可能会新加一个 block 来记录,而导致磁盘空间的变化!不过,一般hard link 所用掉的关连数据量很小,所以通常不会改变 inode 与磁盘空间的大小喔!

      由于 hard link 是在同一个 partition 上面进行数据关连的建立,所以 hard link 是有限制的:
            ? 不能跨 Filesystem;
            ? 不能 link 目录。
      不能跨 Filesystem 还好理解,因为 hard link 本来就是在一个 partition 内建立关连性的, 那不能 hard link 到目录又是怎么回事呢?这是因为如果使用 hard link 连结到目录时, 连结的数据被需要连同被连结目录底下的所有数据都建立连结,因此造成环境相当大的复杂度。目前 hard link 对于目录暂时还是不支持.

      2)    symbol link
    

      相对于 hard link , Symbolic link 可就好理解多了,基本上,Symbolic link 就是在建立一个独立的档案, 而这个档案会让数据的读取指向他 link 的那个档案内容!由于只是利用档案来做为指向的动作, 所以,当来源档被删除之后,symbolic link 的档案会『开不了』, 会一直说『无法开启某档案!』。这里还是得特别留意,这个 Symbolic Link 与 Windows 的快捷方式可以给他划上等号,由 Symbolic link 所建立的档案为一个独立的新的档案,所以会占用掉 inode 与block 喔!

      由上面的说明来看,似乎 hard link 比较安全,因为即使某一个目录下的关连数据被杀掉了, 也没有关系,只要有任何一个目录下存在着关连数据,那么该档案就不会不见!举上面的例子来说,我的 /etc/crontab 与 /root/crontab 指向同一个档案,如果我删除了 /etc/crontab 这个档案,该删除的动作其实只是将 /etc 目录下关于 crontab 的关连数据拿掉而已, crontab 所在的 inode 与 block 其实都没有被变动喔! 

      不过,不幸的是,由于 Hard Link 的限制太多了,包括无法做『目录』的 link , 所以在用途上面是比较受限的!反而是 Symbolic Link 的使用方面较广喔!好了, 说的天花乱坠,看您也差不多快要昏倒了!没关系,实作一下就知道怎么回事了!要制作连结档就必须要使用 ln 这个指令(具体用法参见help)呢!

   
关于目录的 link 数量:

或许您已经发现了,那就是,当我们以 hard link 进行『档案的连结』时,可以发现,在 ls -l 所显示的第二字段会增加一才对,
那么如果建立目录时,他预设的 link 数量会是多少? 让我们来想一想,一个『空目录』里面至少会存在些什么?呵呵!就是存在 . 与 .. 这两个目录啊! 那么,当我们建立一个新目录名称为 /tmp/testing 时,基本上会有三个东西,那就是:
• /tmp/testing
• /tmp/testing/.
• /tmp/testing/..
而其中 /tmp/testing 与 /tmp/testing/. 其实是一样的!都代表该目录啊~而 /tmp/testing/.. 则代表/tmp 这个目录,所以说,当我们建立一个新的目录时, 『新的目录的 link 数为 2 ,而上层目录的 link数则会增加 1 』