29 2008

ext2文件系统分析(一)

Posted by ideal


    Filesystem HOWTO上的关于ext2文件系统的结构图,把每个文件系统boot sector单独画出来,不在Block group之内。如下图:

fs

  通过dumpe2fs发现,我的/dev/sda1的块大小为1024字节,sda1本身比较小,是/boot分区,情况确实如上图所示。即Group 0是从块1开始的,即块0作为boot sector单独在 block group之外。而/dev/sda5并不是这样。sda5的块大小为4096字节。Group 0是从块0开始的。没有把boot sector单独放在外面。但块0的前1024字节仍预留。因此文件系统的主超级块都是从偏移地址1024开始的。并且ext2/ext3的超级块大小为1024字节。如果块大小为1024,超级块正好占用一个块。如果块大小为4096,块0的1024-2047为超级块,而2048-4095则空闲。块的计数从0开始,在一个文件系统上是全局的。

ext2

  这样的设计也避免了块的大小为4096字节时把前一个块留给boot sector有点浪费。
  并且并不是每个block group中都有super block和group descriptors的备份。只是在某些奇数的块中才有(具体的机制不清楚)。

  ext2超级块的结构(在源代码树的include/linux/ext2_fs.h中)。 

/*
 * Structure of the super block
 */
struct ext2_super_block {
    __le32    s_inodes_count;        /* inode总数 */
    __le32    s_blocks_count;        /* block总数 */
    __le32    s_r_blocks_count;    /* 保留的block总数 */
    __le32    s_free_blocks_count;    /* 空闲的block总数 */
    __le32    s_free_inodes_count;    /* 空闲的inode总数 */
    __le32    s_first_data_block;    /* 第一个数据块 */
    __le32    s_log_block_size;    /* Block的大小 */
    __le32    s_log_frag_size;    /* Fragment size */
    __le32    s_blocks_per_group;    /* 每个block group的block数量 */
    __le32    s_frags_per_group;    /* # Fragments per group */
    __le32    s_inodes_per_group;    /* 每个block group的inode数量 */
    __le32    s_mtime;        /* 挂载时间 */
    __le32    s_wtime;        /* Write time */
    __le16    s_mnt_count;        /* 挂载计数 */
    __le16    s_max_mnt_count;    /* Maximal mount count */
    __le16    s_magic;        /* Magic 签名 */
    __le16    s_state;        /* File system state */
    __le16    s_errors;        /* Behaviour when detecting errors */
    __le16    s_minor_rev_level;     /* minor revision level */
    __le32    s_lastcheck;        /* 上一次检查时间 */
    __le32    s_checkinterval;    /* max. time between checks */
    __le32    s_creator_os;        /* OS */
    __le32    s_rev_level;        /* Revision level */
    __le16    s_def_resuid;        /* Default uid for reserved blocks */
    __le16    s_def_resgid;        /* Default gid for reserved blocks */
    /*
     * These fields are for EXT2_DYNAMIC_REV superblocks only.
     *
     * Note: the difference between the compatible feature set and
     * the incompatible feature set is that if there is a bit set
     * in the incompatible feature set that the kernel doesn’t
     * know about, it should refuse to mount the filesystem.
     *
     * e2fsck’s requirements are more strict; if it doesn’t know
     * about a feature in either the compatible or incompatible
     * feature set, it must abort and not try to meddle with
     * things it doesn’t understand…
     */
    __le32    s_first_ino;         /* First non-reserved inode */
    __le16   s_inode_size;         /* inode structure 的大小*/
    __le16    s_block_group_nr;     /* block group # of this superblock */
    __le32    s_feature_compat;     /* compatible feature set */
    __le32    s_feature_incompat;     /* incompatible feature set */
    __le32    s_feature_ro_compat;     /* readonly-compatible feature set */
    __u8    s_uuid[16];        /* 128-bit uuid for volume */
    char    s_volume_name[16];     /* volume name */
    char    s_last_mounted[64];     /* directory where last mounted */
    __le32    s_algorithm_usage_bitmap; /* For compression */
    /*
     * Performance hints.  Directory preallocation should only
     * happen if the EXT2_COMPAT_PREALLOC flag is on.
     */
    __u8    s_prealloc_blocks;    /* Nr of blocks to try to preallocate*/
    __u8    s_prealloc_dir_blocks;    /* Nr to preallocate for dirs */
    __u16    s_padding1;
    /*
     * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
     */
    __u8    s_journal_uuid[16];    /* uuid of journal superblock */
    __u32    s_journal_inum;        /* 日志文件的inode号 */
    __u32    s_journal_dev;        /* 日志文件的设备号 */
    __u32    s_last_orphan;        /* start of list of inodes to delete */
    __u32    s_hash_seed[4];        /* HTREE hash seed */
    __u8    s_def_hash_version;    /* Default hash version to use */
    __u8    s_reserved_char_pad;
    __u16    s_reserved_word_pad;
    __le32    s_default_mount_opts;
     __le32    s_first_meta_bg;     /* First metablock block group */
    __u32    s_reserved[190];    /* Padding to the end of the block */
};

  superblock的大小为1024个字节。ext2和ext3的magic签名是一样的。ext3增加了日志功能。

  可以使用xxd -s 1024 -l 1024 /dev/sdax(将x替换为你要查看的盘块号)来获得这些数据信息

screenshot

  此处第一个32位的数为0x0000cbf0(i386为Little-Endian,即高字节在高地址,低字节在低地址),转换为十进制即52208,所以该分区inode的数目最多为52208,这和使用dumpe2fs得到的结果是一样的。其他的值可按同样的方法得到。

Leave a Reply

评论: