super block

super block的中文名称是超级块,它是硬盘分区开头——开头的第一个byte是byte 0,从 byte 1024开始往后的一部分数据。由于 block size最小是 1024 bytes,所以super block可能是在block 1中(此时block 的大小正好是 1024 bytes),也可能是在block 0中。 超级块中的数据其实就是文件卷的控制信息部分,也可以说它是卷资源表,有关文件卷的大部分信息都保存在这里。例如:硬盘分区中每个block的大小、硬盘分区上一共有多少个block group、以及每个block group中有多少个inode。

目录

一、预备知识
二、super block的结构和涵义
三、super block的几个重要成员
展开

编辑本段一、预备知识

1、block

  对于ext2(ext3类似)文件系统来说,硬盘分区首先被划分为一个个的block,同一个ext2文件系统上的每个block大小都是一样的。但是对于不同的ext2文件系统,block的大小可以有区别。典型的block大小是1024 bytes或者4096 bytes。这个大小在创建ext2文件系统的时候被决定,它可以由系统管理员指定,也可以由文件系统的创建程序根据硬盘分区的大小,自动选择一个较合理的值。
  一个硬盘分区上的block计数是从0开始的,并且这个计数对于这个硬盘分区来说是全局性质的。

2、block group和group descriptor

  硬盘分区中所有block被聚在一起分成几个大的block group,其中每个block group中有多少个block是固定的。
  每个block group都相对应一个group descriptor,这些group descriptor被聚在一起放在硬盘分区的开头部分,跟在super block的后面。在每个group descriptor当中有几个重要的block指针,指向block group的inode table、block bitmap和inode bitmap。
  3、inode table、block bitmap、inode bitmap  以上三个结构记载了其所属block group的许多信息,他们依次被存放在这个block group的开头部分,由该block group所对应的group descriptor中的指针所指向。

编辑本段二、super block的结构和涵义

  struct ext3_super_block {
  /*00*/ __u32 s_inodes_count; /* inodes 计数 */
  __u32 s_blocks_count; /* blocks 计数 */
  __u32 s_r_blocks_count; /* 保留的 blocks 计数 */
  __u32 s_free_blocks_count; /* 空闲的 blocks 计数 */
  /*10*/ __u32 s_free_inodes_count; /* 空闲的 inodes 计数 */
  __u32 s_first_data_block; /* 第一个数据 block */
  __u32 s_log_block_size; /* block 的大小 */
  __s32 s_log_frag_size; /* 可以忽略 */
  /*20*/ __u32 s_blocks_per_group; /* 每 block group 的 block 数量 */
  __u32 s_frags_per_group; /* 可以忽略 */
  __u32 s_inodes_per_group; /* 每 block group 的 inode 数量 */
  __u32 s_mtime; /* Mount time */
  /*30*/ __u32 s_wtime; /* Write time */
  __u16 s_mnt_count; /* Mount count */
  __s16 s_max_mnt_count; /* Maximal mount count */
  __u16 s_magic; /* Magic 签名 */
  __u16 s_state; /* File system state */
  __u16 s_errors; /* Behaviour when detecting errors */
  __u16 s_minor_rev_level; /* minor revision level */
  /*40*/ __u32 s_lastcheck; /* time of last check */
  __u32 s_checkinterval; /* max. time between checks */
  __u32 s_creator_os; /* 可以忽略 */
  __u32 s_rev_level; /* Revision level */
  /*50*/ __u16 s_def_resuid; /* Default uid for reserved blocks */
  __u16 s_def_resgid; /* Default gid for reserved blocks */
  __u32 s_first_ino; /* First non-reserved inode */
  __u16 s_inode_size; /* size of inode structure */
  __u16 s_block_group_nr; /* block group # of this superblock */
  __u32 s_feature_compat; /* compatible feature set */
  /*60*/ __u32 s_feature_incompat; /* incompatible feature set */
  __u32 s_feature_ro_compat; /* readonly-compatible feature set */
  /*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */
  /*78*/ char s_volume_name[16]; /* volume name */
  /*88*/ char s_last_mounted[64]; /* directory where last mounted */
  /*C8*/ __u32 s_algorithm_usage_bitmap; /* 可以忽略 */
  __u8 s_prealloc_blocks; /* 可以忽略 */
  __u8 s_prealloc_dir_blocks; /* 可以忽略 */
  __u16 s_padding1; /* 可以忽略 */
  /*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
  /*E0*/ __u32 s_journal_inum; /* 日志文件的 inode 号数 */
  __u32 s_journal_dev; /* 日志文件的设备号 */
  __u32 s_last_orphan; /* start of list of inodes to delete */
  /*EC*/ __u32 s_reserved[197]; /* 可以忽略 */
  };

编辑本段三、super block的几个重要成员

1、Magic 签名

  对于ext2和ext3文件系统来说,这个字段的值应该正好等于0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的ext2或ext3文件系统。

2、s_log_block_size

  从这个字段,我们可以得出真正的block的大小。我们把真正block的大小记作B,B=1 << s_log_block_size + 10),单位是bytes。举例来说,如果这个字段是0,那么block的大小就是 1024bytes,这正好就是最小的block大小;如果这个字段是2,那么block大小就是4096 bytes。从这里我们就得到了block的大小这一非常重要的数据。

3、s_blocks_count和s_blocks_per_group

  通过这两个成员,我们可以得到硬盘分区上一共有多少个block group,或者说一共有多少个group descriptors
  s_blocks_count记录了硬盘分区上的block的总数,而s_blocks_per_group记录了每个group中有多少个block。显然,文件系统上的block groups数量,我们把它记作G,G=(s_blocks_count-s_first_data_block-1)/s_blocks_per_group+1。为什么要减去s_first_data_block,因为s_blocks_count是硬盘分区上全部的block的数量,而在s_first_data_block之前的block是不归block group管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些block,这些block我们要把它划在一个相对较小的group里面。

4、s_inodes_per_group

  s_inodes_per_group记载了每个block group中有多少个inode。在从已知的inode号,读取这个inode数据的过程中,s_inodes_per_group起到了至关重要的作用。
  用我们得到的inode号数除以s_inodes_per_group,我们就知道了我们要的这个inode是在哪一个block group里面,这个除法的余数也告诉我们,我们要的这个inode是这个block group里面的第几个inode;然后,我们可以先找到这个block group的group descriptor,从这个descriptor,我们找到这个group的inode table,再从inode table找到我们要的第几个 inode,再以后,我们就可以开始读取inode中的用户数据了。这个公式是这样的:
  block_group = (ino - 1) / s_inodes_per_group。这里ino就是我们的inode号数
  offset = (ino - 1) % s_inodes_per_group,这个offset就指出了我们要的inode是这个block group里面的第几个inode。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值