zoukankan      html  css  js  c++  java
  • Linux EXT 文件系统 详解

    上几章我们讲到了Linux启动的一些问题,接下来我们来看一下硬盘分割和EXT格式文件系统的问题。前面提到了分区表的问题,分区表位于MBR, 占用64个字节。所谓的硬盘分区也就是对硬盘进行规划,填写分区表的配置。硬盘默认分区表仅能写入四组分区信息。这四个主要分区我们称之为主分区和拓展分区,而后拓展分区里面又可以划分多个逻辑分区。
    先让我们模拟一块硬盘:

    dd if=/dev/zero of=zero bs=1M count=100

    这样就创建了一个数据块,我们将之看待为一块硬盘,对它进行分区。先看一下这个硬盘

    root@hpdm-machine:~/test# fdisk zero
    Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
    Building a new DOS disklabel with disk identifier 0x536c709e.
    Changes will remain in memory only, until you decide to write them.
    After that, of course, the previous content won't be recoverable.
    
    Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
    
    Command (m for help): p
    
    Disk zero: 104 MB, 104857600 bytes
    255 heads, 63 sectors/track, 12 cylinders, total 204800 sectors 磁头 扇区 磁柱 扇区总数
    Units = sectors of 1 * 512 = 512 bytes 一个扇区512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x536c709e
    
    Device Boot      Start         End      Blocks   Id  System

    我们看了一下 大概也就是说这块硬盘当前没有一个有效的分区表,fdisk 就帮我们建立一个DOS 分区表 并表示磁盘标识是0x536c709e。当我们输入w时写入生效。下面我们来尝试一下分区。m可查看帮助。

    Command (m for help): p
    
    Disk zero: 104 MB, 104857600 bytes
    255 heads, 63 sectors/track, 12 cylinders, total 204800 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x87bc6369
    
    Device Boot      Start         End      Blocks   Id  System
     zero1            2048      100000       48976+  83  Linux
     zero2          100001      150000       25000   83  Linux
     zero3          150001      170000       10000   83  Linux
     zero4          170001      190000       10000    5  Extended
    
    Command (m for help): n
    All primary partitions are in use
    Adding logical partition 5
    First sector (172049-190000, default 172049): 

    这里我做了四个分区 3个主分区,一个拓展分区,当我再试图分区时 只能够添加逻辑分区。所以也就是最多可以有四个主分区。这也就是第一个逻辑分区为什么是/dev/sda5开始的原因。
    下面再看一下EXT文件系统:
    这边将一个50M的数据块格式化EXT4格式。

    root@hpdm-machine:~/test# mkfs -t ext4 zero 
    mke2fs 1.42.9 (4-Feb-2014)
    zero is not a block special device.
    Proceed anyway? (y,n) y
    Discarding device blocks: done                            
    Filesystem label=
    OS type: Linux
    Block size=1024 (log=0)
    Fragment size=1024 (log=0)
    Stride=0 blocks, Stripe width=0 blocks
    12824 inodes, 51200 blocks
    2560 blocks (5.00%) reserved for the super user
    First data block=1
    Maximum filesystem blocks=52428800
    7 block groups  ----------> 分组
    8192 blocks per group, 8192 fragments per group
    1832 inodes per group
    Superblock backups stored on blocks: 
        8193, 24577, 40961
    
    Allocating group tables: done                            
    Writing inode tables: done                            
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done

    格式化之后 硬盘布局大概是这样
    这里写图片描述
    我们也可以看到被分成了几个组。然我们看一下文件系统的信息

    root@hpdm-machine:~/test# dumpe2fs zero 
    dumpe2fs 1.42.9 (4-Feb-2014)
    Filesystem volume name:   <none>
    Last mounted on:          <not available>
    Filesystem UUID:          cdbabe16-2374-4f77-b177-dc44602d51e8
    Filesystem magic number:  0xEF53
    Filesystem revision #:    1 (dynamic)
    Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
    Filesystem flags:         signed_directory_hash 
    Default mount options:    user_xattr acl
    Filesystem state:         clean
    Errors behavior:          Continue
    Filesystem OS type:       Linux
    Inode count:              12824
    Block count:              51200
    Reserved block count:     2560
    Free blocks:              44668
    Free inodes:              12813
    First block:              1
    Block size:               1024
    Fragment size:            1024
    Reserved GDT blocks:      199
    Blocks per group:         8192
    Fragments per group:      8192
    Inodes per group:         1832
    Inode blocks per group:   229
    Flex block group size:    16
    Filesystem created:       Tue Jan  3 13:01:46 2017
    Last mount time:          n/a
    Last write time:          Tue Jan  3 13:01:46 2017
    Mount count:              0
    Maximum mount count:      -1
    Last checked:             Tue Jan  3 13:01:46 2017
    Check interval:           0 (<none>)
    Lifetime writes:          4387 kB
    Reserved blocks uid:      0 (user root)
    Reserved blocks gid:      0 (group root)
    First inode:              11
    Inode size:           128
    Journal inode:            8
    Default directory hash:   half_md4
    Directory Hash Seed:      136ace1b-3264-4454-b473-c2941317098f
    Journal backup:           inode blocks
    Journal features:         (none)
    Journal size:             4096k
    Journal length:           4096
    Journal sequence:         0x00000001
    Journal start:            0
    
    以上 superblock
    
    以下 Group descriptors
    Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
      Checksum 0xb91b, unused inodes 1821
      Primary superblock at 1, Group descriptors at 2-2
      Reserved GDT blocks at 3-201
      Block bitmap at 202 (+201), Inode bitmap at 218 (+217)
      Inode table at 234-462 (+233)
      6360 free blocks, 1821 free inodes, 2 directories, 1821 unused inodes
      Free blocks: 229-233, 1838-8192
      Free inodes: 12-1832

    这些信息都是保存在超级块中, 包含inode 数 block数 挂载次数 剩余inode数 block数 块大小 还有日志的一些信息等等。

    root@hpdm-machine:~/test# dumpe2fs zero | grep superblock
    dumpe2fs 1.42.9 (4-Feb-2014)
      Primary superblock at 1, Group descriptors at 2-2
      Backup superblock at 8193, Group descriptors at 8194-8194
      Backup superblock at 24577, Group descriptors at 24578-24578
      Backup superblock at 40961, Group descriptors at 40962-40962

    superblock有一个primary的还有几个用来备份恢复用的。一旦超级块全部被损坏 那这块硬盘就无能无力了。这里可以看到superblock占用了一个块 1024bytes

    紧接着我们可以看到Group descriptors 也是1024bytes,这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。

    现在我们看看一个Group中的 Block bitmap 和 Inode bitmap

    先看一下什么是inode 和block

    那么文件系统是如何运行的呢?这与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外, 通常含有非常多的属性,例如 Linux
    操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。 文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到
    inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock)
    会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。

    每个 inode 与 block 都有编号,至于这三个数据的意义可以简略说明如下:

    superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量,
    以及文件系统的格式与相关信息等; inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
    block:实际记录文件的内容,若文件太大时,会占用多个 block 。 由于每个 inode 与 block
    都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码。
    因此,我们可以知道的是,如果能够找到文件的 inode 的话,那么自然就会知道这个文件所放置数据的 block 号码,
    当然也就能够读出该文件的实际数据了。这是个比较有效率的作法,因为如此一来我们的磁盘就能够在短时间内读取出全部的数据, 读写的效能比较好啰。

    这个解释够清楚吧。

    block bitmap (区块对照表) 如果你想要新增文件时总会用到 block 吧!那你要使用哪个 block
    来记录呢?当然是选择『空的 block 』来记录新文件的数据啰。 那你怎么知道哪个 block 是空的?这就得要透过 block
    bitmap 的辅助了。从 block bitmap 当中可以知道哪些 block
    是空的,因此我们的系统就能够很快速的找到可使用的空间来处置文件啰。

    同样的,如果你删除某些文件时,那么那些文件原本占用的 block 号码就得要释放出来, 此时在 block bitmap 当中相对应到该
    block 号码的标志就得要修改成为『未使用中』啰!这就是 bitmap 的功能。

    inode bitmap (inode 对照表) 这个其实与 block bitmap 是类似的功能,只是 block bitmap
    记录的是使用与未使用的 block 号码, 至于 inode bitmap 则是记录使用与未使用的 inode 号码啰!

    让我们再刚才建立的文件系统里面分别创建一个目录和文件看一下两张表变化。
    创建了一个目录
    这里写图片描述
    这里写图片描述
    我们可以看到inode和block都减少了一个 挂载次数加了一
    创建文件也好 inode 数量和 block数量时刻在变化, 由此可以看出目录也占用一个inode和一个block,至于文件的整个读取过程可以参考

    目录树读取: 好了,经过上面的说明你也应该要很清楚的知道 inode 本身并不记录文件名,文件名的记录是在目录的 block 当中。
    因此在第六章文件与目录的权限说明中, 我们才会提到『新增/删除/更名文件名与目录的 w 权限有关』的特色!那么因为文件名是记录在目录的
    block 当中, 因此当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode
    号码, 最终才会读到正确的文件的 block 内的数据。

    由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 filesystem 的最顶层 inode
    号码会由 2 号开始喔!),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block
    内的文件名数据,再一层一层的往下读到正确的档名。

    举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?

    [root@www ~]# ll -di / /etc /etc/passwd
    2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 / 1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc 1914888 -rw-r–r–
    1 root root 1945 Sep 29 02:21 /etc/passwd 在鸟哥的系统上面与 /etc/passwd
    有关的目录与文件数据如上表所示,该文件的读取流程为(假设读取者身份为 vbird 这个一般身份使用者):

    / 的 inode: 透过挂载点的信息找到 /dev/hdc2 的 inode 号码为 2 的根目录 inode,且 inode
    规范的权限让我们可以读取该 block 的内容(有 r 与 x) ;

    / 的 block: 经过上个步骤取得 block 的号码,并找到该内容有 etc/ 目录的 inode 号码 (1912545);

    etc/ 的 inode: 读取 1912545 号 inode 得知 vbird 具有 r 与 x 的权限,因此可以读取 etc/ 的
    block 内容;

    etc/ 的 block: 经过上个步骤取得 block 号码,并找到该内容有 passwd 文件的 inode 号码 (1914888);

    passwd 的 inode: 读取 1914888 号 inode 得知 vbird 具有 r 的权限,因此可以读取 passwd 的
    block 内容;

    passwd 的 block: 最后将该 block 内容的数据读出来。

    整个EXT文件系统详细内容可参考:http://cn.linux.vbird.org/linux_basic/0230filesystem.php#fdisk

  • 相关阅读:
    手动删除木马程序
    病毒注册表常用目标Svchost和Explorer
    对电脑假死现象的修复
    "添加与删除程序"报rundll32错误
    通过注册表regedit对Windows回收站进行恢复
    Win7的话,可能有十种简单的方法进行提速呢
    Windows死机的话,可能的一些猫病
    Android开发发布真机调试
    Java Web-----JSP与Servlet(一)
    Java——Log4j与Log4j2
  • 原文地址:https://www.cnblogs.com/MaAce/p/7755711.html
Copyright © 2011-2022 走看看