Ext2文件系统简单剖析(一)

1.ext2文件系统结构

我们都知道,磁盘时存储文件用的,但是磁盘必须先格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理磁盘中的文件。下图为ext2文件系统的存储布局。

ext2文件系统结构概貌.jpeg

磁盘中最小存储单元是扇区(1扇区=512Bytes),而文件系统的最小存储单元就是Block(一般地,1Block = 4KB = 8 扇区)。扇区大小在磁盘出厂就已经定了,而Block大小是在格式化时决定的。例如, mke2fs -b 4096 /dev/sda6 在格式化 /dev/sda6时指定了Block大小为4096Bytes。

在上图中,MBR是主引导记录,它的作用是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序调入内存加以执行。MBR后面的分区可以是NTFS,也可以是ext2的。这里我们主要分析ext2文件系统,ext2文件系统由以下几部分组成:

  1. Boot Sector:上图启动块(Boot Sector),是用来存储磁盘分区信息和启动信息,任何文件系统给都不能缺少启动块。启动块大小并不是我们前面所说的4KB,而是1KB,是由PC标准定义的。

  2. Block Group:启动块之后才是ext2文件系统的开始。ext2文件系统将整个分区划分为大小相等的块组(Block Group),每个块组由以下部分组成:

  3. Super Block:超级块主要有两个功能:1)超级块结构给出了文件系统的全局信息。例如块大小,文件系统的版本等等。2)超级块结构包含一些函数指针,例如super_operation的成员函数read_inode提供了读取inode信息的功能。每个具体的文件系统一般都要提供这个函数来实现对inode信息的读取,例如ext2文件系统提供的具体函数是ext2_read_inode。

    struct super_block {
        unsigned long s_blocksize;//指定了文件系统的块大小
        unsigned char s_blocksize_bits;
        ……/*省略超级块的链表、设备号等代码*/
        unsigned long long s_maxbytes; /* 指定文件系统中最大文件的尺寸 */
    
        struct file_system_type *s_type;/*s_type是指向file_system_type结构的指针。*/
        struct super_operations *s_op;
    
        unsigned long s_magic;
        struct dentry *s_root;/*s_root是指向文件系统根dentry的指针。*/
    
        struct list_head s_inodes; /* all inodes */
        struct list_head  s_dirty; /* dirty inodes */
    
        struct block_device *s_bdev;
        void  *s_fs_info; /* Filesystem private info */
     };
    
  4. GDT(Group Descriptor Table),组描述符表。由很多组描述符组成,整个分区分成多少个组就对应有多少个组描述符。每个组描述符(Group Descriptor)存储一个组的描述信息,例如在这个组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。

    从上图可以看出,超级块和组描述符被复制到每个块组中,因为一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。只有块组0中包含的超级块和组描述符才被内核使用,当执行e2fsck检查文件系统一致性时,第0个块组中的超级块和块组描述符表就会拷贝到其它块组,这样当第0个块组的开头意外损坏时就可以用其它拷贝来恢复,从而减少损失。

  5. Block Bitmap,块位图。块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。这里引出两个问题:

    1.为什么用df命令比du命令统计整个磁盘的已用空间非常快呢?
    因为df命令只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用du命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。

    Linux df命令用于显示目前在Linux系统上的文件系统的磁盘使用情况统计。
    Linux du命令用于显示目录或文件的大小。
    详情可参照:http://www.runoob.com/linux/linux-comm-df.html
    http://www.runoob.com/linux/linux-comm-du.html

    2. 在格式化一个分区时究竟会划出多少个块组呢?
    这主要取决于分区大小和块的大小。我们考虑一个32GB的ext2分区,块大小为4KB,Block Bitmap占一个块,也就是4KB,可以标注4K*8=32K个块,即128MB。因此,一个32GB的ext2分区需要32GB/128MB=256个块组。

  6. inode Bitmap,inode位图,和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。

  7. inode Table,inode表。一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中。每个文件都有一个inode,一个块组中的所有inode组成了inode表。每个inode占128B。

    inode表占多少个块在格式化时就要决定并写入块组描述符中,mke2fs格式化工具的默认策略是一个块组有多少个8KB就分配多少个inode。

  8. Data Block:数据块。
    对于常规文件的内容存储在数据块中。
    对于目录,使用一个目录项的数据结构存储在数据块中。每个目录项存储了文件的文件名,inode号,文件类型,记录长度。这里引出三个问题:
    1. 要存一个hello的文件,具体步骤是?
    1)内核加载块组0中的GDT,从GDT中找出inode bitmap,从inode bitmap中找出inode table中空闲的inode。
    2)申请一个inode。inode主要包含两部分内容:文件属性(68Bytes),数据块指针(60Bytes)。数据块指针指向存储hello文件目录项和文件内容的Data Block。
    3)将文件内容和文件的目录信息分别存在对应的Data Block中。
    4)修改对应的inode Bitmap 和 Block Bitmap。

    2. 给定文件路径“/home/hello”,操作系统时如何找到该文件的位置?
    1)查找根目录的目录项。Linux有规定,根目录的目录项必须存放在2号inode中。
    2)根目录的目录项中存着根目录下的子目录目录项和文件的数据块信息。通过根目录的目录项可以找到home对应的inode。
    3)根据home对应的inode找到home的目录项。
    4)在home目录项中找到hello文件的inode。
    5)根据hello文件的inode中的数据块指针找到存储有hello文件内容的数据块。

    3. 如何删除hello文件?
    1)找到hello文件位置。
    2)将Block Bitmap中对应bit置为0
    3)将inode Bitmap中对应bit置为0

2.数据块寻址

在第一节里面我们提到,操作系统在查找文件时,会根据inode中数据块指针找到对应的Data Block。本节我们介绍数据块寻址。下图为寻址过程。


上文我们说到一个inode中数据块指针占了60Bytes,其中每一个指针占4字节,一共有60/4=15个指针。从上图可以看出,索引项Blocks[12-13]分别指向一级,二级,三级的间接寻址块。因此对于一个inode来说,最多可存储(12+256+2562+2563)*4KB的数据。

这种寻址方式对于访问不超过12个数据块的小文件是非常快的,访问文件中的任意数据只需要两次读盘操作,一次读inode(也就是读索引项)一次读数据块。而访问大文件中的数据则需要最多五次读盘操作:inode、一级间接寻址块、二级间接寻址块、三级间接寻址块、数据块。实际上,磁盘中的inode和数据块往往已经被内核缓存了,读大文件的效率也不会太低。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容