Unix/Linux系统编程(EXT2文件系统)
一.关于文件系统(参考链接:https://blog.csdn.net/TABE_/article/details/122439713)
1.文件类型
操作系统的基本文件类型有普通文件、目录文件、设备文件和链接文件。
          普通文件:最常见的文件。
          目录文件:目录文件中保存着该目录下其他文件的inode号和文件名等信息,目录文件中的每个目录项都是指向某个文件inode号的链接,删除文件名就等于删除与之对应的链接。
          设备文件:操作系统把各种设备也抽象成文件,便于管理,如鼠标,键盘等。
          链接文件:多个文件名指向同一索引节点(inode index)是存在的,这时就会出现链接文件。
2.文件操作
       文件操作分为以下几种:创建文件,删除文件,读文件,写文件等。
          创建文件:在创建一个新文件时,系统首先要为新文件分配必要的外存空间,并在文件系统的目录中,为之建立一个目录项,目录项中应该记录新文件的文件名及其在外存的地址等属性。
          删除文件:当已不再需要某文件时,可将其从文件系统中删除,在删除时,系统应先从目录中找到要删除文件的目录项,使之成为空项,然后回收该文件所占用的存储空间。
          读文件:读文件时,须在相应系统调用中给出文件名和应读入的内存目标地址。此时,系统要查找目录,找到指定目录项,从中得到被读文件在外存中的位置。在目录项中,还有一个指针用于对文件进行读/写。
          写文件:写文件时,须在相应系统调用中给出文件名和其在内存源地址。此时,系统要查找目录,找到指定目录项,从再利用目录中的写指针进行写操作。
文件系统对文件进行操作的过程:
1.先进入目录,目录中有相应的目录项
2.目录项中有对应的文件名和inode号,根据文件名找到对应的inode号
3.再根据inode号读取到文件的inode,分析是否符合inode中记录的权限
4.如果符合权限,则可以读取到相应的data blocks
3.文件系统中数据的存储
文件包括属性和内容两部分(当然,还包括文件名,不过文件名实质是其所属目录文件的内容,目录文件也有inode号)。其中属性信息放置于inode区(即元数据区)中,实际内容放置于data block区中,另外,还有一个superblock(超级块)会记录整个文件系统的整体信息。
    inode
    inode存放文件的属性信息(如文件类型、大小、权限等)和文件内容所在的block编号。inode是文件惟一标识,系统根据文件名先找到inode,并首先分析是否符合inode中记录的权限,符合后根据block编号找到数据块读取内容。
    block(块)
    block存放文件实际内容。每个block大小有1K,2K及4K三种,其大小也是在磁盘(或分区)格式化时就确定了。每个block内只能存放一个文件的内容。若文件内容大小大于单个block,则该文件会占用多个block;若占不满一个block,这个block中的剩余空间也将浪费。因此block大小的选取也很重要,若经常存储小文件,而block较大无疑会浪费很多空间;但block较小的话,大型文件会占用较多的block数,这样inode中也会记录更多的block编号,由此会降低系统读写性能。所以block大小的选取应根据实际情况权衡。

    superblock(超级块)
    superblock存放此文件系统的整体信息,包括inode/block大小、inode/block总量、使用量、剩余量、文件系统格式等。一个文件系统仅有一个superblock,位于组0中,这个块很重要,因此通常还有一个备份位于其它组中,其大小一般为1K。
关于文件系统的基础知识(包括文件系统的储存方式及分配方式,推荐参考链接:https://blog.csdn.net/u012489236/article/details/123808924)
二.EXT2文件系统
1.EXT2文件系统数据结构
1.1通过mkfs创建虚拟磁盘
在Linux系统下,使用命令:mke2fs [-b blksize -N ninodes] device nblocks ,可以在设备上创建一个带有nblocks个块(每块大小为blksize字节)和ninodes个索引节点的EXT2文件系统。
例如使用下面的命令:
dd if=/dev/zero of=vdisk bs=1024 count=1440
mkes2fs vdisk 1440
作用:在一个名为vdisk的虚拟磁盘文件上创建一个EXT2文件系统,有1440个大小为1KB的块。

 
1.2虚拟磁盘布局(参考链接:https://blog.csdn.net/qq_43909184/article/details/105142341)

        如图为简单的EXT2文件系统布局,可以看出,ext2文件系统将整个分区划成若干个同样大小的块组(Block Group),从Block Group 0 到Block Group n(图中设定n=1440)。
      (1)启动块(boot block)
        文件系统中存储的最小单位是块(Block),而上图中启动块(Boot Block)的大小是确定的,就是1KB,启动块是由PC标准规定的,用来存储磁盘分区信息和启动信息,任何文件系统都不能使用启动块。启动块之后才是ext2文件系统的开始。
      (2)Block Group
        ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
      (3)超级块(Super Block)
        存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。
      (4)块组描述符表(GDT,Group Descriptor Table)
        块组描述符表是由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。
      (5)块位图(Block Bitmap)
        Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用。
      (6)inode位图(inode Bitmap)
        每个bit表示一个inode是否空闲可用。
      (7)i节点表
        包含文件/目录的几乎全部-适用于放置在硬盘上的,需要长久保存的信息。
        例如:文件所有者,文件类型,i节点号(存放在目录块中),主次设备号,连接计数,访问/修改时间,IO块长,文件字节数等等。
        可以用stat函数(#include )获取相关i节点信息信息。
(8)数据区:存放文件内容
1.3文件索引过程

dentry是一个目录项(Directory entry),相当于一个文件目录,该文件目录里面有很多文件。其实本质就是一个dir_entry结构体,重要成员有文件的inode索引号,文件名等,存储着文件的信息。

2.遍历EXT2文件系统树
      (1)读取超级块。检查幻数s_magic(0xEF53),验证它确实是 EXT2 FS。
      (2)读取块组描述符块(1+s_first_data_block),以访问组0描述符。从块组描述符的bg_ inode_table条目中找到索引节点的起始块编号,并将其称为InodesBeginBlock。
      (3)读取InodeBeginBlock,获取/的索引节点,即INODE #2。
      (4)将路径名标记为组件字符串,假设组件数量为 n。例如,如果路径名=/a/b/c,则组件字符串是"a""b""c",其中n=3。用name[0],name[1],…,name[n-1]来表示组件。
      (5)从(3)中的根索引节点开始,在其数据块中搜索 name[0]。为简单起见,我们可以假设某个目录中的条目数量很少,因此一个目录索引节点只有12个直接数据块。有了这个假设,就可以在12个(非零)直接块中搜索 name[0]。目录索引节点的每个数据块都包含以下形式的 dir_entry结构体:
[ino rec_len name_len NAME] [ino rec_len name_len NAME] . . . . .
其中NAME是一系列nlen字符,不含终止NULL。对于每个数据块,将该块读入内存并使用dir_entry*dp指向加载的数据块。然后使用name_len将NAME提取为字符串,并与name[0]进行比较。
      (6)使用索引节点号ino 来定位相应的索引节点。回想前面的内容,ino 从1开始计数。使用邮差算法计算包含索引节点的磁盘块及其在该块中的偏移量。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号