2016-12-30

1.目标/任务

主要为了验证对ext2的 Disk Organization的理解, 诸如Block Group Descriptor, Inode Table之类.
给定一个ext2镜像, 遍历其所有文件, 并显示文件内容.
假定该镜像的文件大小都比较小, 不需要indirect pointer.

2.源码

ext2_parse.c

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>

#define dbg_print(fmt,args...)\
    printf("%s(),%d:"fmt, __func__, __LINE__, ##args)
#define info_print(fmt,args...)\
        printf("%s(),%d:"fmt, __func__, __LINE__, ##args)

typedef unsigned int __le32;
typedef unsigned int __u32;
typedef unsigned short __le16;
typedef unsigned short __u16;
typedef unsigned char __u8;
/*
主要为了验证对ext2的 Disk Organization的理解, 诸如Block Group Descriptor, Inode Table之类.
1. 不考虑大小端问题
2. 处理file hole的情况
3. 处理block size不为1024的情况
   简化, 忽略indirect pointer的情况
*/
enum {
    EXT2_FT_UNKNOWN        = 0,
    EXT2_FT_REG_FILE    = 1,
    EXT2_FT_DIR        = 2,
    EXT2_FT_CHRDEV        = 3,
    EXT2_FT_BLKDEV        = 4,
    EXT2_FT_FIFO        = 5,
    EXT2_FT_SOCK        = 6,
    EXT2_FT_SYMLINK        = 7,
    EXT2_FT_MAX
};

struct ext2_super_block {
    __le32    s_inodes_count;        /* Inodes count */
    __le32    s_blocks_count;        /* Blocks count */
    __le32    s_r_blocks_count;    /* Reserved blocks count */
    __le32    s_free_blocks_count;    /* Free blocks count */
    __le32    s_free_inodes_count;    /* Free inodes count */
    __le32    s_first_data_block;    /* First Data Block */
    /*[Professional Linux Kernel Architecture] 
    Currently, the three values 0, 1, and 2 are used
    表示 block sizes of 20 × 1,024 = 1,024, 21 × 1,024 = 2,048,
    and 22 × 1,024 = 4,096 bytes
    */
    __le32    s_log_block_size;    /* Block size */
    __le32    s_log_frag_size;    /* Fragment size */
    __le32    s_blocks_per_group;    /* # Blocks per group */
    __le32    s_frags_per_group;    /* # Fragments per group */
    __le32    s_inodes_per_group;    /* # Inodes per group */
    __le32    s_mtime;        /* Mount time */
    __le32    s_wtime;        /* Write time */
    __le16    s_mnt_count;        /* Mount count */
    __le16    s_max_mnt_count;    /* Maximal mount count */
    __le16    s_magic;        /* Magic signature */
    __le16    s_state;        /* File system state */
    __le16    s_errors;        /* Behaviour when detecting errors */
    __le16    s_minor_rev_level;     /* minor revision level */
    __le32    s_lastcheck;        /* time of last check */
    __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;         /* size of 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 number of journal file */
    __u32    s_journal_dev;        /* device number of journal file */
    __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 */
};

struct ext2_group_desc
{    
    __le32    bg_block_bitmap;        /* Blocks bitmap block */
    __le32    bg_inode_bitmap;        /* Inodes bitmap block */
    __le32    bg_inode_table;        /* Inodes table block */
    __le16    bg_free_blocks_count;    /* Free blocks count */
    __le16    bg_free_inodes_count;    /* Free inodes count */
    __le16    bg_used_dirs_count;    /* Directories count */
    __le16    bg_pad;
    __le32    bg_reserved[3];
};

struct ext2_inode {
    __le16    i_mode;        /* File mode */
    __le16    i_uid;        /* Low 16 bits of Owner Uid */
    __le32    i_size;        /* Size in bytes */
    __le32    i_atime;    /* Access time */
    __le32    i_ctime;    /* Creation time */
    __le32    i_mtime;    /* Modification time */
    __le32    i_dtime;    /* Deletion Time */
    __le16    i_gid;        /* Low 16 bits of Group Id */
    __le16    i_links_count;    /* Links count */
    __le32    i_blocks;    /* Blocks count  用来处理file hole, 单位为512字节 */
    __le32    i_flags;    /* File flags */
    union {
        struct {
            __le32  l_i_reserved1;
        } linux1;
        #if 0 //awakening-fong.github.io 只管linux的
        struct {
            __le32  h_i_translator;
        } hurd1;
        struct {
            __le32  m_i_reserved1;
        } masix1;
        #endif
    } osd1;                /* OS dependent 1 */
    #define EXT2_N_BLOCKS (15)
    __le32    i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
    __le32    i_generation;    /* File version (for NFS) */
    __le32    i_file_acl;    /* File ACL */
    __le32    i_dir_acl;    /* Directory ACL */
    __le32    i_faddr;    /* Fragment address */
    union {
        struct {
            __u8    l_i_frag;    /* Fragment number */
            __u8    l_i_fsize;    /* Fragment size */
            __u16    i_pad1;
            __le16    l_i_uid_high;    /* these 2 fields    */
            __le16    l_i_gid_high;    /* were reserved2[0] */
            __u32    l_i_reserved2;
        } linux2;
        #if 0 //awakening-fong.github.io 只管linux的
        struct {
            __u8    h_i_frag;    /* Fragment number */
            __u8    h_i_fsize;    /* Fragment size */
            __le16    h_i_mode_high;
            __le16    h_i_uid_high;
            __le16    h_i_gid_high;
            __le32    h_i_author;
        } hurd2;
        struct {
            __u8    m_i_frag;    /* Fragment number */
            __u8    m_i_fsize;    /* Fragment size */
            __u16    m_pad1;
            __u32    m_i_reserved2[2];
        } masix2;
        #endif
    } osd2;                /* OS dependent 2 */
};
struct ext2_dir_entry_2 {
    __le32    inode;            /* Inode number */
    __le16    rec_len;        /* Directory entry length */
    __u8    name_len;        /* Name length */
    __u8    file_type;
    char    name[];            /* File name, up to EXT2_NAME_LEN */
};
struct ext2_dir_entry {
    __le32    inode;            /* Inode number */
    __le16    rec_len;        /* Directory entry length */
    __le16    name_len;        /* Name length */
    char    name[];            /* File name, up to EXT2_NAME_LEN */
};



int inodes_per_group;
int block_size=0;
int blocks_per_group;
void list_file(char *buf,struct ext2_inode *dir_inode);
static int FileIn( const char *strFile, unsigned char *inBuff)
{

    FILE *p_in=NULL;
    if((p_in = fopen(strFile,"rb")) == NULL)
    {
       dbg_print("open file:%s error!\n",strFile);
       return -1;
    }

    fseek(p_in, 0L, SEEK_END);
    unsigned int file_size = ftell(p_in);
    fseek(p_in, 0L,SEEK_SET);
    dbg_print("ftell size %d\n", file_size);

    ssize_t nread=0;
    size_t nleft =file_size;
    unsigned char *bufp = inBuff;
    while (nleft > 0)
    {
       if ((nread = fread(bufp, nleft,1,p_in)) == -1) 
       {
            if (errno == EINTR) /* interrupted by signal handler return */
                nread = 0;      /* and call read() again */
            else
                return -1;      /* errno set by read() */
        }
        else if (nread == 0)
            break;              /* EOF */
        nleft -= nread;
        bufp += nread;
    }

    dbg_print("file read size %u\n", file_size);
    fclose(p_in);
    p_in=NULL;
    return file_size;

}


//group descriptors分布在各个block group中的内容是一样的.
struct ext2_inode *get_inode_buf(char *buf, int inode)
{
    //inode编号从1开始.
    int group_th=inode/inodes_per_group;
    char *p;
//    dbg_print("group_th:%d\n",group_th);    
    int first_desc_table_nr_block=((1024+1024)+(block_size-1))/block_size;//copy from main()
    struct ext2_group_desc *p_desc =(struct ext2_group_desc *) (buf + first_desc_table_nr_block * block_size);
    p_desc+=group_th;
    int dst_block=p_desc->bg_inode_table;
//    dbg_print("bg_inode_table:%d\n",dst_block);
    //block编号从0开始
    p=buf + dst_block*block_size;
    //inode编号从1开始.
    p+=(inode-1)%inodes_per_group * sizeof(struct ext2_inode);
    return (struct ext2_inode*)p;
}


void read_from_ext2_dir_entry_2(char *buf,struct ext2_dir_entry_2 *entry)
{
    if(EXT2_FT_DIR==entry->file_type)
    {
        dbg_print("start  list file for %s\n",entry->name);
        struct ext2_inode *dir_inode=get_inode_buf(buf, entry->inode);
        list_file(buf,dir_inode);
        dbg_print("end of list_file %s\n",entry->name);
    }
    else if(EXT2_FT_REG_FILE==entry->file_type)
    {
        struct ext2_inode *file_inode=get_inode_buf(buf, entry->inode);

        int sum_size=0;
        int j=0;
        while(1)
        {
            int i=0;
            int block_th=file_inode->i_block[j]; 
//            dbg_print("block_th:%d\n",block_th);
            /*
            这个是错误的写法, 因为没有考虑file hole的情况.
            if(0==block_th)
                break;
            */
            if(0==block_th)
            {

                //XXX     暂不考虑indirect的情况
                if( (j+1)*block_size<file_inode->i_size )
                {
                    j++;
                    continue;
                }
                else
                    break;

            }


            //XXX     暂不考虑indirect的情况
            //dbg_print("block_th:%d\n",block_th);
            char *p=buf + block_th* block_size;

            //dbg_print("inode i_size:%d\n",root_inode->i_size);
            do
            {
                printf("%c",p[i++]);
                sum_size++;
            }while(i<block_size && sum_size < file_inode->i_size );
            j++;
        }
    }
}

void list_file(char *buf,struct ext2_inode *dir_inode)
{

    int i=0;
    while(1)
    {
        int block_th=dir_inode->i_block[i]; 
        //dbg_print("block_th:%d\n",block_th);

        //a regular file才有file hole
        if(0==block_th)
            break;
        char *p=buf + block_th* block_size;
        struct ext2_dir_entry_2*p_dir_entry=(struct ext2_dir_entry_2*)p;

        int sum_size=0;
        //dbg_print("inode i_size:%d\n",dir_inode->i_size);

        if(0==p_dir_entry->inode) //https://courses.cs.washington.edu/courses/cse451/09sp/projects/project3light/project3_light.html
        {
            dbg_print("p_dir_entry inode:%d\n",p_dir_entry->inode);
            break;
        }
        /*
        if(0==strlen(p_dir_entry->name))
            break;
        */    
        do
        {
//            if(EXT2_FT_DIR==p_dir_entry->file_type)
                //info_print("dir:\n");

            //dbg_print("%s  lel:%d\n",p_dir_entry->name,strlen(p_dir_entry->name));
            dbg_print("%s\n",p_dir_entry->name);
            if(!(strlen(p_dir_entry->name)==1 && p_dir_entry->name[0]=='.')
            && !(strlen(p_dir_entry->name)==2 && 0==strcmp(p_dir_entry->name,"..")))
                read_from_ext2_dir_entry_2(buf,p_dir_entry);
            sum_size+=p_dir_entry->rec_len;
            p+=p_dir_entry->rec_len;
            //dbg_print("sum_size:%d\n",sum_size);//tmp_fong
            p_dir_entry=(struct ext2_dir_entry_2*)p;
        //}while(sum_size<block_size && sum_size<dir_inode->i_size);
        /*为何要sum_size<block_size ???*/
        }while(sum_size<block_size && sum_size<dir_inode->i_blocks*512); //XXX 先不管file hole
        //}while(sum_size<dir_inode->i_blocks*512); //XXX 先不管file hole
        i++;

    }

}


int main(int argc, char *argv[])
{
int file_size=-1;
unsigned char *buf=(unsigned char *)malloc(70*1024*1024);
if (!buf)
{
dbg_print("malloc fail\n");
return -1;
}
file_size=FileIn(argv[1],buf);
if(file_size<0)
{
dbg_print("FileIn fail\n");
return -1;
}

struct ext2_super_block super_block;
memset(&super_block, 0, sizeof(super_block));
/*
The Superblock is always located at byte 1024 from the beginning of the volume and is exactly 1024 bytes in length.
(来自 http://wiki.osdev.org/Ext2)
*/
memcpy(&super_block, buf+1024, sizeof(super_block));
dbg_print("sizeof(super_block):%d\n",sizeof(super_block));
dbg_print("s_magic:0x%x\n",super_block.s_magic);
assert(super_block.s_magic==0xef53);
dbg_print("s_log_block_size:%d\n",super_block.s_log_block_size);

if(0==super_block.s_log_block_size)
    block_size=1024;
else if(1==super_block.s_log_block_size)
    block_size=2048;
else if(2==super_block.s_log_block_size)
    block_size=4096;
else
    exit(-1);
dbg_print("block_size:%d\n",block_size);

inodes_per_group=super_block.s_inodes_per_group;
blocks_per_group=super_block.s_blocks_per_group;


/*遍历group*/
const int nr_group=(super_block.s_blocks_count+blocks_per_group -1)/blocks_per_group;
dbg_print("nr_group:%d\n",nr_group);
int i=0;
struct ext2_super_block *p_sb;
char *p;
for( i=0; i<nr_group ; i++  )
{
    if(i==0)
        p = buf + 1024 + i*blocks_per_group * block_size;
    else
        p = buf + 1024*(1024>=block_size) + i*blocks_per_group * block_size;
    p_sb=(struct ext2_super_block *)p;
//        __le16    s_block_group_nr;     /* block group # of this superblock */
    dbg_print("s_block_group_nr:%d\n",p_sb->s_block_group_nr);
}


/*遍历group descriptors*/
int first_desc_table_nr_block=((1024+1024)+(block_size-1))/block_size;
struct ext2_group_desc *p_desc =(struct ext2_group_desc *) (buf + first_desc_table_nr_block * block_size);
for( i=0; i<nr_group ; i++)
{
dbg_print("group %d:\n",i);
dbg_print("bg_block_bitmap:%d\n",p_desc->bg_block_bitmap);
dbg_print("bg_inode_bitmap:%d\n",p_desc->bg_inode_bitmap);
dbg_print("bg_inode_table:%d\n\n",p_desc->bg_inode_table);
p_desc += 1;
}

//递归显示 各目录下的文件名及内容
struct ext2_inode *root_inode=get_inode_buf(buf,2); //root dir
dbg_print("root_inode->i_size:%d\n",root_inode->i_size);
list_file(buf,root_inode);
//free(buf); we donot care this.
return 0;
}

3. 验证

3.1 脚本

$ cat ext2_layout.sh 
file_img="img.70M_2048"
rm $file_img a.out
orig_path=$PWD
dd if=/dev/zero of=$file_img bs=1M count=70
/sbin/mke2fs -b 2048 -O ^sparse_super,^has_journal,^dir_index,^resize_inode $file_img <<EOF
y
EOF
mkdir /mnt/ext2
umount /mnt/ext2
/sbin/losetup -d /dev/loop0
/sbin/losetup  /dev/loop0  $file_img
/sbin/mkfs.ext2 /dev/loop0
mount -t ext2 /dev/loop0 /mnt/ext2/
cd /mnt/ext2
echo file_root_01_01234567aaaaaaaabbbbbbbbccccccccdddddddd >> root_01
echo file_root_02_01234567aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee >> root_02
echo file_root_03_01234567aaaaaaaabbbbbbbbccccccccddddddddffffffff >> root_03
mkdir d.home d.lib d.usr d.boot
cd d.boot/
echo file_in_d.boot_file00_named_file00_end_of_file >> file00
echo file_in_d.boot_file01_named_file01_end_of_file >> file01
echo -n "X" | dd of=file02_file_hole bs=1024 seek=6
sync
sync
umount /mnt/ext2
sync
echo $orig_path > /dev/stderr
cd $orig_path
gcc -m32 ext2_parse.c && ./a.out $file_img
#dumpe2fs $file_img

3.2 脚本执行结果

$ sudo sh ext2_layout.sh 
70+0 records in
70+0 records out
73400320 bytes (73 MB) copied, 0.8425 seconds, 87.1 MB/s
mke2fs 1.39 (29-May-2006)
img.70M_2048 is not a block special device.
Proceed anyway? (y,n) Filesystem label=
OS type: Linux
Block size=2048 (log=1)
Fragment size=2048 (log=1)
17952 inodes, 35840 blocks
1792 blocks (5.00%) reserved for the super user
First data block=0
3 block groups
16384 blocks per group, 16384 fragments per group
5984 inodes per group
Superblock backups stored on blocks: 
    16384, 32768

Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
mkdir: cannot create directory `/mnt/ext2': File exists
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
17928 inodes, 71680 blocks
3584 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
9 block groups
8192 blocks per group, 8192 fragments per group
1992 inodes per group
Superblock backups stored on blocks: 
    8193, 24577, 40961, 57345

Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 22 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
0+1 records in
0+1 records out
1 byte (1 B) copied, 7.9348e-05 seconds, 12.6 kB/s
umount: /mnt/ext2: device is busy
umount: /mnt/ext2: device is busy
/opt/drivr_study/ext2_parse
FileIn(),227:ftell size 73400320
FileIn(),247:file read size 73400320
main(),428:sizeof(super_block):1024
main(),429:s_magic:0xef53
main(),431:s_log_block_size:0
main(),441:block_size:1024
main(),449:nr_group:9
main(),461:s_block_group_nr:0
main(),461:s_block_group_nr:1
main(),461:s_block_group_nr:0
main(),461:s_block_group_nr:3
main(),461:s_block_group_nr:0
main(),461:s_block_group_nr:5
main(),461:s_block_group_nr:0
main(),461:s_block_group_nr:7
main(),461:s_block_group_nr:0
main(),470:group 0:
main(),471:bg_block_bitmap:259
main(),472:bg_inode_bitmap:260
main(),473:bg_inode_table:261

main(),470:group 1:
main(),471:bg_block_bitmap:8451
main(),472:bg_inode_bitmap:8452
main(),473:bg_inode_table:8453

main(),470:group 2:
main(),471:bg_block_bitmap:16385
main(),472:bg_inode_bitmap:16386
main(),473:bg_inode_table:16387

main(),470:group 3:
main(),471:bg_block_bitmap:24835
main(),472:bg_inode_bitmap:24836
main(),473:bg_inode_table:24837

main(),470:group 4:
main(),471:bg_block_bitmap:32769
main(),472:bg_inode_bitmap:32770
main(),473:bg_inode_table:32771

main(),470:group 5:
main(),471:bg_block_bitmap:41219
main(),472:bg_inode_bitmap:41220
main(),473:bg_inode_table:41221

main(),470:group 6:
main(),471:bg_block_bitmap:49153
main(),472:bg_inode_bitmap:49154
main(),473:bg_inode_table:49155

main(),470:group 7:
main(),471:bg_block_bitmap:57603
main(),472:bg_inode_bitmap:57604
main(),473:bg_inode_table:57605

main(),470:group 8:
main(),471:bg_block_bitmap:65537
main(),472:bg_inode_bitmap:65538
main(),473:bg_inode_table:65539

main(),479:root_inode->i_size:1024
list_file(),386:.
list_file(),386:..
list_file(),386:lost+found
read_from_ext2_dir_entry_2(),300:start  list file for lost+found
list_file(),386:.
list_file(),386:..
list_file(),373:p_dir_entry inode:0
read_from_ext2_dir_entry_2(),303:end of list_file lost+found
list_file(),386:root_01
file_root_01_01234567aaaaaaaabbbbbbbbccccccccdddddddd
list_file(),386:root_02
file_root_02_01234567aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
list_file(),386:root_03
file_root_03_01234567aaaaaaaabbbbbbbbccccccccddddddddffffffff
list_file(),386:d.home
read_from_ext2_dir_entry_2(),300:start  list file for d.home
list_file(),386:.
list_file(),386:..
read_from_ext2_dir_entry_2(),303:end of list_file d.home
list_file(),386:d.lib
read_from_ext2_dir_entry_2(),300:start  list file for d.lib
list_file(),386:.
list_file(),386:..
read_from_ext2_dir_entry_2(),303:end of list_file d.lib
list_file(),386:d.usr
read_from_ext2_dir_entry_2(),300:start  list file for d.usr
list_file(),386:.
list_file(),386:..
read_from_ext2_dir_entry_2(),303:end of list_file d.usr
list_file(),386:d.boot
read_from_ext2_dir_entry_2(),300:start  list file for d.boot
list_file(),386:.
list_file(),386:..
list_file(),386:file00
file_in_d.boot_file00_named_file00_end_of_file
list_file(),386:file01
file_in_d.boot_file01_named_file01_end_of_file
list_file(),386:file02_file_hole
Xread_from_ext2_dir_entry_2(),303:end of list_file d.boot

3.3 dumpe2fs

$ dumpe2fs img.70M_2048 
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          dc4c52d6-692e-4d99-a8bb-ed363dd83472
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      resize_inode dir_index filetype sparse_super
Default mount options:    (none)
Filesystem state:         not clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              17928
Block count:              71680
Reserved block count:     3584
Free blocks:              68116
Free inodes:              17917
First block:              1
Block size:               1024
Fragment size:            1024
Reserved GDT blocks:      256
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1992
Inode blocks per group:   249
Filesystem created:       Thu Jan 29 02:59:27 2015
Last mount time:          Thu Jan 29 02:59:27 2015
Last write time:          Thu Jan 29 02:59:27 2015
Mount count:              1
Maximum mount count:      22
Last checked:             Thu Jan 29 02:59:27 2015
Check interval:           15552000 (6 months)
Next check after:         Tue Jul 28 02:59:27 2015
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:          128
Default directory hash:   tea
Directory Hash Seed:      a46ae30c-3b9f-410d-856b-1c29adc3c0b6


Group 0: (Blocks 1-8192)
  Primary superblock at 1, Group descriptors at 2-2
  Reserved GDT blocks at 3-258
  Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
  Inode table at 261-509 (+260)
  7666 free blocks, 1978 free inodes, 2 directories
  Free blocks: 524-1024, 1028-8192
  Free inodes: 15-1992
Group 1: (Blocks 8193-16384)
  Backup superblock at 8193, Group descriptors at 8194-8194
  Reserved GDT blocks at 8195-8450
  Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
  Inode table at 8453-8701 (+260)
  7683 free blocks, 1992 free inodes, 0 directories
  Free blocks: 8702-16384
  Free inodes: 1993-3984
Group 2: (Blocks 16385-24576)
  Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
  Inode table at 16387-16635 (+2)
  7940 free blocks, 1991 free inodes, 1 directories
  Free blocks: 16636-24064, 24066-24576
  Free inodes: 3986-5976
Group 3: (Blocks 24577-32768)
  Backup superblock at 24577, Group descriptors at 24578-24578
  Reserved GDT blocks at 24579-24834
  Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
  Inode table at 24837-25085 (+260)
  7683 free blocks, 1992 free inodes, 0 directories
  Free blocks: 25086-32768
  Free inodes: 5977-7968
Group 4: (Blocks 32769-40960)
  Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
  Inode table at 32771-33019 (+2)
  7937 free blocks, 1988 free inodes, 1 directories
  Free blocks: 33020-33280, 33282-33792, 33795-40448, 40450-40960
  Free inodes: 7973-9960
Group 5: (Blocks 40961-49152)
  Backup superblock at 40961, Group descriptors at 40962-40962
  Reserved GDT blocks at 40963-41218
  Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
  Inode table at 41221-41469 (+260)
  7682 free blocks, 1991 free inodes, 1 directories
  Free blocks: 41470-48640, 48642-49152
  Free inodes: 9962-11952
Group 6: (Blocks 49153-57344)
  Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
  Inode table at 49155-49403 (+2)
  7940 free blocks, 1991 free inodes, 1 directories
  Free blocks: 49404-56832, 56834-57344
  Free inodes: 11954-13944
Group 7: (Blocks 57345-65536)
  Backup superblock at 57345, Group descriptors at 57346-57346
  Reserved GDT blocks at 57347-57602
  Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
  Inode table at 57605-57853 (+260)
  7683 free blocks, 1992 free inodes, 0 directories
  Free blocks: 57854-65536
  Free inodes: 13945-15936
Group 8: (Blocks 65537-71679)
  Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
  Inode table at 65539-65787 (+2)
  5892 free blocks, 1992 free inodes, 0 directories
  Free blocks: 65788-71679
  Free inodes: 15937-17928

本文地址: https://awakening-fong.github.io/posts/fs/ext2_layout

转载请注明出处: https://awakening-fong.github.io


若无法评论, 请打开JavaScript, 并通过proxy.


blog comments powered by Disqus