ext2 disk layout
2016-12-30
1.目标/任务
主要为了验证对ext2的 Disk Organization的理解, 诸如Block Group Descriptor, Inode Table之类.
给定一个ext2镜像, 遍历其所有文件, 并显示文件内容.
假定该镜像的文件大小都比较小, 不需要indirect pointer.
给定一个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