ext2硬盘layout如下:
下面做了ext2的一些验证,主要为了验证对ext2的 Disk Organization的理解, 诸如Block Group Descriptor, Inode Table之类.
给定一个ext2镜像, 遍历其所有文件, 并显示文件内容.假定该镜像的文件大小都比较小, 不需要indirect pointer.ext2_parse.c:
#include#include #include #include #include #include #include #include #include #include #include #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 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 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 i_size); /*为何要sum_size i_blocks*512); //XXX 先不管file hole //}while(sum_size 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 =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 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 dirdbg_print("root_inode->i_size:%d\n",root_inode->i_size);list_file(buf,root_inode);//free(buf); we donot care this.return 0;}
验证脚本:
$ cat ext2_layout.sh file_img="img.70M_2048"rm $file_img a.outorig_path=$PWDdd 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 <> root_01echo file_root_02_01234567aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee >> root_02echo file_root_03_01234567aaaaaaaabbbbbbbbccccccccddddddddffffffff >> root_03mkdir d.home d.lib d.usr d.bootcd d.boot/echo file_in_d.boot_file00_named_file00_end_of_file >> file00echo file_in_d.boot_file01_named_file01_end_of_file >> file01echo -n "X" | dd of=file02_file_hole bs=1024 seek=6syncsyncumount /mnt/ext2syncecho $orig_path > /dev/stderrcd $orig_pathgcc -m32 ext2_parse.c && ./a.out $file_img#dumpe2fs $file_img
验证结果:
$ sudo sh ext2_layout.sh 70+0 records in70+0 records out73400320 bytes (73 MB) copied, 0.8425 seconds, 87.1 MB/smke2fs 1.39 (29-May-2006)img.70M_2048 is not a block special device.Proceed anyway? (y,n) Filesystem label=OS type: LinuxBlock size=2048 (log=1)Fragment size=2048 (log=1)17952 inodes, 35840 blocks1792 blocks (5.00%) reserved for the super userFirst data block=03 block groups16384 blocks per group, 16384 fragments per group5984 inodes per groupSuperblock backups stored on blocks: 16384, 32768Writing inode tables: done Writing superblocks and filesystem accounting information: doneThis filesystem will be automatically checked every 28 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.mkdir: cannot create directory `/mnt/ext2': File existsmke2fs 1.39 (29-May-2006)Filesystem label=OS type: LinuxBlock size=1024 (log=0)Fragment size=1024 (log=0)17928 inodes, 71680 blocks3584 blocks (5.00%) reserved for the super userFirst data block=1Maximum filesystem blocks=673710089 block groups8192 blocks per group, 8192 fragments per group1992 inodes per groupSuperblock backups stored on blocks: 8193, 24577, 40961, 57345Writing inode tables: done Writing superblocks and filesystem accounting information: doneThis filesystem will be automatically checked every 22 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.0+1 records in0+1 records out1 byte (1 B) copied, 7.9348e-05 seconds, 12.6 kB/sumount: /mnt/ext2: device is busyumount: /mnt/ext2: device is busy/opt/drivr_study/ext2_parseFileIn(),227:ftell size 73400320FileIn(),247:file read size 73400320main(),428:sizeof(super_block):1024main(),429:s_magic:0xef53main(),431:s_log_block_size:0main(),441:block_size:1024main(),449:nr_group:9main(),461:s_block_group_nr:0main(),461:s_block_group_nr:1main(),461:s_block_group_nr:0main(),461:s_block_group_nr:3main(),461:s_block_group_nr:0main(),461:s_block_group_nr:5main(),461:s_block_group_nr:0main(),461:s_block_group_nr:7main(),461:s_block_group_nr:0main(),470:group 0:main(),471:bg_block_bitmap:259main(),472:bg_inode_bitmap:260main(),473:bg_inode_table:261main(),470:group 1:main(),471:bg_block_bitmap:8451main(),472:bg_inode_bitmap:8452main(),473:bg_inode_table:8453main(),470:group 2:main(),471:bg_block_bitmap:16385main(),472:bg_inode_bitmap:16386main(),473:bg_inode_table:16387main(),470:group 3:main(),471:bg_block_bitmap:24835main(),472:bg_inode_bitmap:24836main(),473:bg_inode_table:24837main(),470:group 4:main(),471:bg_block_bitmap:32769main(),472:bg_inode_bitmap:32770main(),473:bg_inode_table:32771main(),470:group 5:main(),471:bg_block_bitmap:41219main(),472:bg_inode_bitmap:41220main(),473:bg_inode_table:41221main(),470:group 6:main(),471:bg_block_bitmap:49153main(),472:bg_inode_bitmap:49154main(),473:bg_inode_table:49155main(),470:group 7:main(),471:bg_block_bitmap:57603main(),472:bg_inode_bitmap:57604main(),473:bg_inode_table:57605main(),470:group 8:main(),471:bg_block_bitmap:65537main(),472:bg_inode_bitmap:65538main(),473:bg_inode_table:65539main(),479:root_inode->i_size:1024list_file(),386:.list_file(),386:..list_file(),386:lost+foundread_from_ext2_dir_entry_2(),300:start list file for lost+foundlist_file(),386:.list_file(),386:..list_file(),373:p_dir_entry inode:0read_from_ext2_dir_entry_2(),303:end of list_file lost+foundlist_file(),386:root_01file_root_01_01234567aaaaaaaabbbbbbbbccccccccddddddddlist_file(),386:root_02file_root_02_01234567aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeelist_file(),386:root_03file_root_03_01234567aaaaaaaabbbbbbbbccccccccddddddddfffffffflist_file(),386:d.homeread_from_ext2_dir_entry_2(),300:start list file for d.homelist_file(),386:.list_file(),386:..read_from_ext2_dir_entry_2(),303:end of list_file d.homelist_file(),386:d.libread_from_ext2_dir_entry_2(),300:start list file for d.liblist_file(),386:.list_file(),386:..read_from_ext2_dir_entry_2(),303:end of list_file d.liblist_file(),386:d.usrread_from_ext2_dir_entry_2(),300:start list file for d.usrlist_file(),386:.list_file(),386:..read_from_ext2_dir_entry_2(),303:end of list_file d.usrlist_file(),386:d.bootread_from_ext2_dir_entry_2(),300:start list file for d.bootlist_file(),386:.list_file(),386:..list_file(),386:file00file_in_d.boot_file00_named_file00_end_of_filelist_file(),386:file01file_in_d.boot_file01_named_file01_end_of_filelist_file(),386:file02_file_holeXread_from_ext2_dir_entry_2(),303:end of list_file d.boot
dumpe2fs:
$ dumpe2fs img.70M_2048 dumpe2fs 1.39 (29-May-2006)Filesystem volume name:Last mounted on: Filesystem UUID: dc4c52d6-692e-4d99-a8bb-ed363dd83472Filesystem magic number: 0xEF53Filesystem revision #: 1 (dynamic)Filesystem features: resize_inode dir_index filetype sparse_superDefault mount options: (none)Filesystem state: not cleanErrors behavior: ContinueFilesystem OS type: LinuxInode count: 17928Block count: 71680Reserved block count: 3584Free blocks: 68116Free inodes: 17917First block: 1Block size: 1024Fragment size: 1024Reserved GDT blocks: 256Blocks per group: 8192Fragments per group: 8192Inodes per group: 1992Inode blocks per group: 249Filesystem created: Thu Jan 29 02:59:27 2015Last mount time: Thu Jan 29 02:59:27 2015Last write time: Thu Jan 29 02:59:27 2015Mount count: 1Maximum mount count: 22Last checked: Thu Jan 29 02:59:27 2015Check interval: 15552000 (6 months)Next check after: Tue Jul 28 02:59:27 2015Reserved blocks uid: 0 (user root)Reserved blocks gid: 0 (group root)First inode: 11Inode size: 128Default directory hash: teaDirectory Hash Seed: a46ae30c-3b9f-410d-856b-1c29adc3c0b6Group 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-1992Group 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-3984Group 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-5976Group 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-7968Group 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-9960Group 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-11952Group 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-13944Group 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-15936Group 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