linux中ext3/4文件系统探索
来源:互联网 发布:阿里云技术架构 编辑:程序博客网 时间:2024/05/22 06:54
前言
前段时间做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/sda1Filesystem volume name: <none>Last mounted on: / Filesystem UUID: 90dcc170-957c-41c6-a0ba-2c3d045fc481Filesystem magic number: 0xEF53Filesystem revision #:1 (dynamic)Filesystem flags: signed_directory_hash Default mount options:user_xattr aclFilesystem state: clean Errors behavior: ContinueFilesystem OS type: Linux Inode count: 30334976Block count: 121309952Reserved block count: 6065497Free blocks: 85495976Free inodes: 30080455First 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:16Filesystem created: Thu Mar 31 02:34:34 2016Last mount time: Wed Aug 24 10:24:20 2016Last write time: Wed Aug 24 10:24:20 2016Mount count: 70Maximum mount count: -1Last checked: Thu Mar 31 02:34:34 2016Reserved blocks gid: 0 (group root) First inode: 11Inode size: 256Required extra isize: 28Desired extra isize: 28Journal inode:8Journal backup: inode blocksJournal features: journal_incompat_revokeJournal size: 128MJournal length: 32768Journal sequence: 0x0001117aJournal start:1Group 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-8192Group 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`</pre>       以上是使用dumpe2fs对本地磁盘的部分查看结果,会列出所有的块组信息,现在只显示前两个块组。这里有一个小细节,我们查看这些块组信息时每次都要重新使用dumpe2fs工具,而且想要查看后面的块组,还要一点一点翻着看,这时我们就可以借助linux的数据流重定向功能,把这些信息定位到一个文件中去。 <pre>`dumpe2fs /dev/sda1 > dump`</pre>       这样我们的磁盘sda1的基本信息就存储在了dump文件中,可以随时快速查看。        从上面的信息中可以看出文件inode总数,磁盘块大小(block size),每个块组磁盘块数(block per group),每个块组inode数,inode大小(inode size)。## 超级块       超级块存放在一个ext_super_block的结构中。在内核结构中,使用了__le16、__le32、__be16、__be32的数据类型,前两种类型分别表示字或双字的“小尾”即小端序的排序方式(低阶字节在高位地址),而后两种类型分别表示字或双字的“大尾”即大端序的排序方式(高阶字节在高位地址)。接下来介绍一下超级块的字段,这里我们引用《深入理解linux内核》这本书中的数据结构截图。![](http://i.imgur.com/Q2s4lUR.png) ![](http://i.imgur.com/Y1LRhnm.png)       在我们对超级块的数据结构有些了解之后,我们开始对磁盘进行字节方面的探索,依旧是使用linux的数据流重定向功能,把文件系统的字节信息输入的指定的文件中去,以便之后查看。<pre>`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计算出文件所在的磁盘块号和扇区号。
- linux中ext3/4文件系统探索
- Linux ext2, ext3, ext4 文件系统解读[4]
- linux日志文件系统-ext3
- Linux ext2/ext3文件系统
- Linux文件系统:ext2/ext3
- Linux ext2/ext3文件系统详解
- Linux ext2/ext3文件系统详解
- linux ext2/ext3文件系统结构图
- Linux ext2/ext3文件系统详解
- Linux ext2/ext3文件系统详解
- Linux 文件系统ext2, ext3, ext4
- Linux EXT3文件系统误删文件恢复
- 初窥Linux 之 ext2/ext3文件系统
- Linux ext3/ext4 文件系统数据恢复
- 浅谈Linux下的EXT3文件系统
- 初窥Linux 之 ext2/ext3文件系统
- 初窥Linux 之 ext2/ext3文件系统
- 初窥Linux 之 ext2/ext3文件系统
- hdu2034 人见人爱A-B
- 欢迎使用CSDN-markdown编辑器
- jdbc
- 今天Unity学习测试总结
- 创建数据表
- linux中ext3/4文件系统探索
- 第六章 计时器
- 解读浮动闭合最佳方案:clearfix
- Android异常收集
- 《c和指针》(三)
- 理解java中的vo,bo,po等概念
- Win\Linux 双系统,如何删除linux的grub引导
- 小波分析解读
- Linux学习笔记 -- day01 基本命令