文档章节

Linux文件系统--【文件系统与分区&Ext3文件系统】

满小茂
 满小茂
发布于 2016/05/23 10:53
字数 2944
阅读 689
收藏 1

3 月,跳不动了?>>>

本文以Ext2文件系统为例讲述Linux文件系统,由于Ext3文件系统是直接从Ext2文件系统发展而来,它完全兼容Ext2文件系统,所以本文的内容对于Ext2和Ext3都是适用的。
 

1.磁盘分区和文件系统

我们首先看一下磁盘分区和文件系统的结构图:

 
  
            图 1 磁盘分区和文件系统结构图
 
整个磁盘可以分为1个MBR(Master Boot Record)和4个partitions。其中MBR的结构示意图如图2所示
 
 

                    图 2 MBR示意图
 
MBR不是本文的主要内容,所以不再详述,有兴趣的开发人员可以参考网址:https://www.ibm.com/developerworks/linux/library/l-linuxboot/。
 
一个partition由两部分组成:Boot Sector和File System。Boot Sector大小是1KB,这是有PC标准规定的,用来存储磁盘分区信息和启动信息,任何File System都不能使用Boot Sector。

 

2.文件系统

详细介绍File System——文件系统。文件系统中存储的最小单位是块(Block),一个块究竟多大是在格式化时确定的,例如mke2fs的-b选项可以设定块大小为1024、2048或4096字节。Ext2文件系统将整个分区划成若干个同样大小的块组(Block Group),如图1所示,每个块组都由以下部分组成:

1.Super Block(超级块)


描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝。
在Linux源代码中,
Super Block对应的结构体如图3:


图 3 ext3_super_block结构体
 
超级块包含以下重要信息:
1)      
  Magic Number
对于Ext2和Ext3文件系统来说,这个字段的值应该正好等于0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的Ext2或Ext3文件系统。从这里,我们也可以估计到,Ext2和Ext3的兼容性一定是很强的,不然的话,Linux内核的开发者应该会为Ext3文件系统另选一个Magic Number才对。
2)        
Mount Count and Maximum Mount Count
每次mount此文件系统,Mount Count都会加1,当它等于Maximum Mount Count时系统将发出警告:maxumal mount count reached, running e2fsck is recommended。
3)         Block Group Number
Block Group的个数。
4)         Block Size
该文件系统在创建(格式化)时指定的block大小,如1024 Bytes。
5)         Blocks per Group
每个Block Group中block的个数,文件系统在创建时指定。
6)         Free Blocks
文件系统中空闲块数。
7)         Free Inodes
文件系统中空闲Inode数。
8)         First Inode
文件系统中第一个inode号。EXT2根文件系统中第一个inode将是指向'/'目录的目录入口。
 

2.GDT(Group Descriptor Table,块组描述符表)

由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。和超级块类似,块组描 述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。通常内核只用到第0个块组中的拷贝,当执行e2fsck检查文件系统一致性时,第0个块组中的超级块和块组描述符表就会拷贝到其它块组,这样当第0个块组的开头意外损坏时就可以用其它拷贝来恢复,从而减少损失。
在Linux源代码中,GDT对应的结构体如图4:
 

struct ext3_group_desc
{
    __le32    bg_block_bitmap;        /* Blocks bitmap block */
    __le32    bg_inode_bitmap;        /* Inodes bitmap block */
    __le32    bg_inode_table;        /* Inodes table block */
    __le16    bg_free_blocks_count;    /* Free blocks count */
    __le16    bg_free_inodes_count;    /* Free inodes count */
    __le16    bg_used_dirs_count;    /* Directories count */
    __u16    bg_pad;
    __le32    bg_reserved[3];
};

ext3_group_desc结构体
 
GDT包含以下重要信息:

1)         Blocks Bitmap
对应此数据块组的块分配位图的块号。在块分配和回收时使用。
2)         Inode Bitmap
对应此数据块组的inode分配位图的块号。在inode分配和回收时使用。
3)         Inode Table
对应数据块组的inode表的起始块号。每个inode用下面5中介绍的ext3_inode结构来表示。
4)         Free blocks count, Free Inodes count, Used directory count
分别代表空闲的block数、空闲的inode数和使用的directory数。
 

3.Block Bitmap(块位图)


一个块组中的块是这样利用的:数据块存储所有文件的数据,比如某个分区的块大小是1024字节,某个文件是2049字节,那么就需要三个数据块来存,即使第三个块只存了一个字节也需要占用一个整块;超级块、块组描述符表、块位图、inode位图、inode表这几部分存储该块组的描述信息。那么如何知道哪些块已经用来存储文件数据或其它描述信息,哪些块仍然空闲可用呢?块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit 代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。
为什么用df命令统计整个磁盘的已用空间非常快呢?因为只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用du命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。
与此相联系的另一个问题是:在格式化一个分区时究竟会划出多少个块组呢?主要的限制在于块位图本身必须只占一个块。用mke2fs格式化时默认块大小是1024字节,可以用-b参数指定块大小,现在设块大小指定为b字节,那么一个块可以有8b个bit,这样大小的一个块位图就可以表示8b个块的占用情况,因此一个块组最多可以有8b个块,如果整个分区有s个块,那么就可以有s/(8b)个块组。格式化时可以用-g参数指定一个块组有多少个块,但是通常不需要手动指定,mke2fs工具会计算出最优的数值。


4.inode Bitmap(inode位图)


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


5.inode Table(inode表)


我们知道,一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中。每个文件都有一个inode,一个块组中的所有inode组成了inode表。
inode表占多少个块在格式化时就要决定并写入块组描述符中,mke2fs格式化工具的默认策略是一个块组有多少个8KB就分配多少个inode。由于数据块占了整个块组的绝大部分,也可以近似认为数据块有多少个8KB就分配多少 个inode,换句话说,如果平均每个文件的大小是8KB,当分区存满的时候inode表会得到比较充分的利用,数据块也不浪费。如果这个分区存的都是很 大的文件(比如电影),则数据块用完的时候inode会有一些浪费,如果这个分区存的都是很小的文件(比如源代码),则有可能数据块还没用完inode就 已经用完了,数据块可能有很大的浪费。如果用户在格式化时能够对这个分区以后要存储的文件大小做一个预测,也可以用mke2fs的-i参数手动指定每多少个字节分配一个inode。
EXT2 inode还可以描叙特殊设备文件。虽然它们不是真正的文件, 但可以通过它们访问设备。所有那些位于/dev中的设备文件可用来存取Linux设备。例如mount程序可把设备文件作为参数。
在Linux源代码中,GDT对应的结构体如图5:
 


图 5 ext3_inode结构体
 
inode包含以下重要信息:

1)         Mode
它包含两类信息;inode描叙的内容以及用户使用权限。EXT2中的inode可以表示一个文件、目录、符号连接、块设备、字符设备或FIFO。
2)         Owner Information
表示此文件或目录所有者的用户和组标志符。文件系统根据它可以进行正确的存取。
3)         Size
以字节计算的文件尺寸。
4)         Timestamps
inode创建及最后一次被修改的时间。
5)         Datablocks Pointers
指向此inode描叙的包含数据的块指针。前12个指针指向包含由inode描叙的物理块, 最后三个指针包含多级间接指针。例如两级间接指针指向一块指针,而这些指针又指向一些数据块。这意味着访问文件尺寸小于或等于12个数据块的文件将比访问大文件快得多。这种寻址方式如图6所示,详细解释如下:我们看到在inode里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指针。用户数据就从这些 block 里面获得。15个blocks不一定放得下全部的用户数据,在这里 ext3 文件系统采取了一种分层的结构。这组15个block指针的前12个是所谓的direct blocks,里面直接存放的就是用户数据。第13个block,也就是所谓的indirect block,里面存放的全部是block指针,这些block指针指向的block才被用来存放用户数据。第 14个block 是所谓的double indirect block,里面存放的全是block指针,这些block指针指向的block也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。第 15个block是所谓的triple indirect block,比上面说的double indirect block有多了一层 block指针。


 
 
图 6 数据块寻址方式

 6.Data Block(数据块)

根据不同的文件类型有以下几种情况
1)         对于常规文件,文件的数据存储在数据块中。
2)         对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中。注意这个概念:目录也是一种文件,是一种特殊类型的文件。
3)         对于符号链接,如果目标路径名较短则直接保存在inode中以便更快地查找,如果目标路径名较长则分配一个数据块来保存。
4)         设备文件、FIFO和socket等特殊文件没有数据块,设备文件的主设备号和次设备号保存在inode中。

© 著作权归作者所有

满小茂
粉丝 80
博文 122
码字总数 138239
作品 0
成都
程序员
私信 提问
加载中

评论(0)

Linux系统环境 Ext3文件系统的使用介绍

Linux缺省情况下使用的文件系统为Ext2,ext2文件系统的确高效稳定。但是,随着Linux系统在关键业务中的应用,Linux文件系统的弱点也渐渐显露出来了;其中系统缺省使用的ext2文件系统是非日志...

范堡
2009/05/07
534
0
Linux创建文件系统及挂载文件系统流程

如果您想加载一个分区(文件系统),首先您得确认文件系统的类型,然后才能挂载使用,比如通过mount 加载,或者通过修改 /etc/fstab来开机自动加载; 如果您想添加一个新的分区,或者增加一个...

JavaGG
2009/05/07
511
0
Linux文件系统类型简介及支持的文件系统汇总--Linux入门到精通系列

不同的操作系统需要使用不同类型的文件系统,为了与其他操作系统兼容,以相互交换数据,通常操作系统都能支持多种类型的文件系统,比如Windows 2000 Server,系统默认或推荐采用的文件系统是N...

长平狐
2012/09/20
1.5K
1
如何在Win7下读取Ext3/Ext4 linux分区

如何在Win7下读取Ext3/Ext4 linux分区 ext3或第三代拓展文件系统是广泛用在Linux kernel上的日志纪录档案系统。它是很多流行Linux发行的默认文件系统。 ext4或第四代文件系统则是继ext3发展起...

xyxzfj
2010/09/25
66
0
Linux 中获取硬盘分区或文件系统的 UUID 的七种方法

作为一个 Linux 系统管理员,你应该知道如何去查看分区的 UUID 或文件系统的 UUID。因为现在大多数的 Linux 系统都使用 UUID 挂载分区。你可以在 文件中可以验证。 有许多可用的实用程序可以...

作者: Magesh Maruthamuthu
2019/04/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

为什么只能在头文件中实现模板? - Why can templates only be implemented in the header file?

问题: Quote from The C++ standard library: a tutorial and handbook : 引用来自C ++标准库:教程和手册 : The only portable way of using templates at the moment is to implement t......

javail
今天
19
0
Gradle 6 针对已有的构建如何创建一个构建扫描

有关构建扫描的定义为: 构建扫描(build scan)是一个中心化并且可以共享的构建记录。这个构建记录通常能够告诉在构建中发生了什么并且为什么会发生。 通过应用构建扫描插件到你的项目中,你...

honeymoose
今天
17
0
C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存

一、malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数。free是进行内存释放的库函数。 1、函数原型 #include <stdlib.h> void *malloc( size_t size ); v...

shzwork
今天
17
0
什么是JavaBean? - What is a JavaBean exactly?

问题: I understood, I think, that a "Bean" is a Java class with properties and getters/setters. 我认为,“ Bean”是具有属性和getter / setter的Java类。 As much as I understand,......

技术盛宴
今天
27
0
深圳援鄂最后一批工作人员归来,88万元关爱金发放至85人

中国公益在线3月31日深圳讯 深圳援鄂最后一批工作人员归来......深圳市民政局、深圳市卫健委和深圳市慈善会发起了“深爱战疫天使基金”项目,联合龙华区慈善会和 永贤慈善基金会,进行第二次...

传承天下融媒体中心
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部