linux中ext3/4文件系统探索

前言

       前段时间做linux虚拟化相关的项目,需要实现一个功能,通过linuxExt3\4文件系统中文件的inode号,计算出该文件在linux文件系统的磁盘块号(blocks)以及扇区号(sectors),基本上算是对linux的EXT文件系统有了较深的理解。这样的一个工作,花费了我很长的时间,网上只是关于文件系统的资料比较多,但牵扯到具体的计算,基本上没有资料。因此,我想在这里,把自己前一段时间的工作成果分享出来,或许能给以后在这方面研究的朋友们一些帮助。

文件inode号

       在介绍EXT文件系统之前,我想先对文件的inode号进行一下说明。

       文件存储在硬盘上,硬盘的最小存储单位叫做扇区(sector)。每个扇区的大小不一,常见512KB。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。文件数据就存放在磁盘块中,inode作为文件的元信息,存储则文件创建者,创建日期,大小,读写权限等。每个文件对应一个唯一inode号。

       每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

EXT文件系统结构

       EXT文件系统的结构如上图所示,首先第一块是启动块——Boot Block,这个里面基本上为0值。
接下来就是一个紧挨着另外一个的块组——Block group(上文提到的块,多个块组成的块组)。每个块组都是相互独立的存储着信息。从图中可以看出,每个块组都会包含下列信息(EXT4稍微有改动,稍后提及)。

  • 一个文件系统超级块的拷贝(占用1块)
  • 一个文件系统组描述符的拷贝(占用n块)
  • 一个数据块位图(占用1块)
  • 一个索引节点位图(占用1块)
  • 一个索引节表(占用n块)
  • 一个大数据块(占用n块)

       由上可知,超级块以及块组描述符内容一样,且只有块组0中所包含的超级块和组描述符才有内核使用,即使这样也会拷贝到所有的块组中,如果出现数据损坏,并且0块组的主超级块和主描述符变为无效,那么系统管理员就可以命令e2fsck引用存放在摸个块组(除了第一个块组)中的超级块和组描述符的旧拷贝(ext4 考虑到在每个块组中都备份有点多余,尤其是组描述符表所以就仅在块号以 3 , 5 , 7 为幂的块组上进行备份。)。那么有多少块组呢?这将取决于文件系统分区的大小和块的大小。

文件系统信息查看

       在深入到文件系统的数据结构之前,我想先介绍文件系统的查看工具dumpe2fs。

dumpe2fs /dev/sda1
Filesystem volume name:   <none>
Last mounted on:  / 
Filesystem UUID:  90dcc170-957c-41c6-a0ba-2c3d045fc481
Filesystem magic number:  0xEF53
Filesystem revision #:1 (dynamic)
Filesystem flags: signed_directory_hash 
Default mount options:user_xattr acl
Filesystem state: clean 
Errors behavior:  Continue
Filesystem OS type:   Linux 
Inode count:  30334976
Block count:  121309952
Reserved block count: 6065497
Free blocks:  85495976
Free inodes:  30080455
First block:  0 
Block size:   4096  
Fragment size:4096  
Reserved GDT blocks:  995   
Blocks per group: 32768 
Fragments per group:  32768 
Inodes per group: 8192  
Inode blocks per group:   512   
Flex block group size:16
Filesystem created:   Thu Mar 31 02:34:34 2016
Last mount time:  Wed Aug 24 10:24:20 2016
Last write time:  Wed Aug 24 10:24:20 2016
Mount count:  70
Maximum mount count:  -1
Last checked: Thu Mar 31 02:34:34 2016
Reserved blocks gid:  0 (group root) 
First inode:  11
Inode size:   256
Required extra isize: 28
Desired extra isize:  28
Journal inode:8
Journal backup:   inode blocks
Journal features: journal_incompat_revoke
Journal size: 128M
Journal length:   32768
Journal sequence: 0x0001117a
Journal start:1

Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
  Checksum 0x9d44, unused inodes 8178
  Primary superblock at 0, Group descriptors at 1-29
  Reserved GDT blocks at 30-1024
  Block bitmap at 1025 (+1025), Inode bitmap at 1041 (+1041)
  Inode table at 1057-1568 (+1057)
  23485 free blocks, 8179 free inodes, 2 directories, 8178 unused inodes
  Free blocks: 9283-32767
  Free inodes: 14-8192
Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0x9df4, unused inodes 8192
  Backup superblock at 32768, Group descriptors at 32769-32797
  Reserved GDT blocks at 32798-33792
  Block bitmap at 1026 (bg #0 + 1026), Inode bitmap at 1042 (bg #0 + 1042)
  Inode table at 1569-2080 (bg #0 + 1569)
  959 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
  Free blocks: 34762-34783, 34810-34815, 56835-56863, 56881-57023, 57047-57055, 57081-57087, 57259-57343, 62126-62431, 62452-62687, 62705-62719, 62911, 62929-62943, 62961-62975, 63281-63295, 63313-63327, 63345-63359, 63463-63487
  Free inodes: 8193-16384

       以上是使用dumpe2fs对本地磁盘的部分查看结果,会列出所有的块组信息,现在只显示前两个块组。这里有一个小细节,我们查看这些块组信息时每次都要重新使用dumpe2fs工具,而且想要查看后面的块组,还要一点一点翻着看,这时我们就可以借助linux的数据流重定向功能,把这些信息定位到一个文件中去。

dumpe2fs /dev/sda1 > dump

       这样我们的磁盘sda1的基本信息就存储在了dump文件中,可以随时快速查看。

       从上面的信息中可以看出文件inode总数,磁盘块大小(block size),每个块组磁盘块数(block per group),每个块组inode数,inode大小(inode size)。

超级块

       超级块存放在一个ext_super_block的结构中。在内核结构中,使用了__le16、__le32、__be16、__be32的数据类型,前两种类型分别表示字或双字的“小尾”即小端序的排序方式(低阶字节在高位地址),而后两种类型分别表示字或双字的“大尾”即大端序的排序方式(高阶字节在高位地址)。接下来介绍一下超级块的字段,这里我们引用《深入理解linux内核》这本书中的数据结构截图。


       在我们对超级块的数据结构有些了解之后,我们开始对磁盘进行字节方面的探索,依旧是使用linux的数据流重定向功能,把文件系统的字节信息输入的指定的文件中去,以便之后查看。

od -tx1 -Ax -N2000 /dev/sda1 > blockinfo

       上述代码的意思就是查看/dev/sda1磁盘块的2000字节的信息,并输出到文件blockinfo中。在这里我的磁盘信息如下图:

       可以看出来,这里的数字全是以16进制进行的。跟我们之前分析的文件系统磁盘结构一样,刚开始有1000字节的空白,代表的是启动块。从第0X400(即第1000字节)开始,就到了第一个块组的范围,第一个块组的头部是超级块,也就是说,从0X400开始,就是第一个超级块。前四个字节是01cee000=30334976(之前说过的小端序),这四个字节代表的是inode count,inode的个数,可以看出来,与刚才在块组信息里面的inode个数一致;接下来四个字节是block count总块数,0X073b0b00=121309952,同样和之前的块组信息里面的总块数一致。这里我只是给大家提供一种方法,如何找到文件系统的数据结构中的各个字段,下面还有很多,朋友们可以自行验证找到所有字段来获取想要得到的信息。需要注意的是各个字段的长度。

块组描述符

       Group Descriptor Tabel 每个块组都有一个专门的数据结构用来描述整个块组的相关信息,即块组描述表,它紧跟在超级块后面的一个块,其每一项称为组描述符,是一个大小为32字节的数据结构。记录组中块位图所在的块号、索引节点位图所在的块号、索引节点表的第一个块号等。

       块组描述符的数据结构如下图:


       还是从之前的块组信息中看到 :Primary superblock at 0, Group descriptors at 1-29,第二块就是快组描述符的位置了。由于每个块大小为4096字节,所以在0x1000开始为第二块,即快组描述符的开始。

       这样我们可以对照数据结构,在这些字节码中,找到需要的信息。

其他结构

       Block Bitmap 即此块组中的块位图,记录此组中的哪些块已经被占用,在分配块时使用。

       Inode Bitmap 即此块组中的索引节点位图,记录本组中的哪些索引节点已经被占用。

       Inode Table 即此块组中的索引节点表,每一项是一个文件的索引,即Inode,记录此文件的相关信息,其中本文最为关心的是地41~100字节,记录着文件所占数据库的信息。

       Data Blocks 即此块组中的数据块,可供分配给各个文件使用。


       在这篇文章中说明了如何查找文件系统中的相关信息的数据结构,接下来探讨如何通过inode计算出文件所在的磁盘块号和扇区号。

ext2/3,扩展文件系统,常用于Linux操作系统。是很多Linux发行版的默认文件系统Linux ext2/ext3文件系统使用索引节点来记录文件信息,作用像windows的文件分配表。 索引节点(inode)是一个结构,它包含了一个文件的长度、创建及修改时间、权限、所属关系、磁盘的位置等信息。 一个文件系统维护了一个索引节点的数组(GroupDesc),每个文件或目录都与索引节点数组的唯一一个元素对应。 系统给每个索引节点分配了一个号码,也就是该节点在数组的索引号,称为索引节点号。 linux文件系统将文件索引节点号和文件名同时保存在目录。所以,目录只是将文件的名称和 它的索引节点号结合在一起的一张表,目录每一对文件名称和索引节点号称为一个连接。 对于一个文件 来说有唯一的索引节点号与之对应,对于一个索引节点号,却可以有多个文件名与之对应。因此,在磁盘 上的同一个文件可以通过不同的路径去访问它。 本程序是一个ext2/ext3文件系统查看器(ext4暂不支持).可以打开镜像文件及硬盘设备文件查看具体的 文件系统结构信息,如超级组信息,文件inode,目录信息,文件信息,提取文件内容等。本人写这个程序就是 为了学习一下ext2/3,也希望通过本程序能让读者了解ext2/3文件系统结构. 具体使用方法请看readme
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值