static void init_fs(){ /* u8 fsbuf[SECTOR_SIZE]; */ MESSAGE message; message.type=INFO_FS_DEVICE; message.device=ROOT_DEVICE; assert(dd_map[DRIVER(ROOT_DEVICE)].driver_pid!=PID_INVALID,""); send_receive(BOTH,dd_map[DRIVER(ROOT_DEVICE)].driver_pid,&message); //如果系统已经是要求的系统,就不需要在格式化系统了 get_super_block(ROOT_DEVICE,&super_block); /* if(super_block.magic!=MAGIC_V1) */{ mkfs(); get_super_block(ROOT_DEVICE,&super_block); } init_inode_table(); init_file_descriptor_table(); #ifdef DEBUG_FS //write test /* memset(fsbuf,0x23,SECTOR_SIZE); */ /* WRITE_SECTOR(ROOT_DEVICE,fsbuf,1); */ //read test u8 fsbuf[SECTOR_SIZE]; READ_SECTOR(ROOT_DEVICE,fsbuf,1); printl("read test:\nfsbuf[0]=%x fsbuf[1]=%x fsbuf[2]=%x fsbuf[3]=%x\n",fsbuf[0],fsbuf[1],fsbuf[2],fsbuf[3]); #endif }
// Return a pointer to a block given its number. // get_block(fs, 0) == fs; void * get_block(void * fs, __u32 block_num) { // Return fs if block_num is 0. if (block_num == 0) { return fs; } // Return super block address if block_num is 1. if (block_num == 1) { return (void*)get_super_block(fs); } // Get the pointer to block 2, which is right after the super block. void * block_2_ptr = (void*)get_super_block(fs) + SUPERBLOCK_SIZE; // Calculate the address of the given block_num. return block_2_ptr + (block_num - 2) * get_block_size(fs); }
/** * Allocate a bit in inode-map. * * @param dev In which device the inode-map is located. * * @return I-node nr. *****************************************************************************/ PRIVATE int alloc_imap_bit(int dev) { int inode_nr = 0; int i, j, k; int imap_blk0_nr = 1 + 1; /* 1 boot sector & 1 super block */ struct super_block * sb = get_super_block(dev); for (i = 0; i < sb->nr_imap_sects; i++) { RD_SECT(dev, imap_blk0_nr + i); for (j = 0; j < SECTOR_SIZE; j++) { /* skip `11111111' bytes */ if (fsbuf[j] == 0xFF) continue; /* skip `1' bits */ for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++) {} /* i: sector index; j: byte index; k: bit index */ inode_nr = (i * SECTOR_SIZE + j) * 8 + k; fsbuf[j] |= (1 << k); /* write the bit to imap */ WR_SECT(dev, imap_blk0_nr + i); break; } return inode_nr; } /* no free bit in imap */ panic("inode-map is probably full.\n"); return 0; }
PRIVATE int alloc_imap_bit(int dev) { int inode_nr = 0; int imap_blk0_nr = 1 + 1; // boot sector + super block struct super_block *sb = get_super_block(dev); for (int i = 0; i < sb->nr_imap_sects; i++) { // 逐扇区遍历 inode map RD_SECT(dev, imap_blk0_nr + i); for (int j = 0; j < SECTOR_SIZE; j++) { // 逐字节 /* 跳过已经使用的(1:使用;0:未使用) */ if (fsbuf[j] == 0xFF) continue; int k = 0; for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++); // 逐位(一位代表一个 inode) inode_nr = (i * SECTOR_SIZE + j) * 8 + k; fsbuf[j] |= (1 << k); /* 将更新后的 inode map 写入磁盘 */ WR_SECT(dev, imap_blk0_nr + i); break; } return inode_nr; } panic("inode-map is probably full.\n"); return 0; }
PRIVATE int alloc_imap_bit(int dev) { int inode_nr = 0; int i, j, k; int imap_blk0_nr = 2; assert(dev == ROOT_DEV); struct super_block *sb = get_super_block(dev); for (i=0; i<sb -> nr_imap_sects; i++) { RD_SECT(dev, imap_blk0_nr+i); for (j=0; j<SECTOR_SIZE; j++) { if (fsbuf[j] == 0xFF) continue; for (k=0; (fsbuf[j] & (1<<k))!=0; k++) ; inode_nr = (i*SECTOR_SIZE + j)*8 + k; fsbuf[j] |= (1<<k); WR_SECT(dev, imap_blk0_nr+i); return inode_nr; } } panic("Inode map is full.\n"); return 0; }
/** * <Ring 1> Do some preparation. * *****************************************************************************/ PRIVATE void init_fs() { int i; /* f_desc_table[] */ for (i = 0; i < NR_FILE_DESC; i++) memset(&f_desc_table[i], 0, sizeof(struct file_desc)); /* inode_table[] */ for (i = 0; i < NR_INODE; i++) memset(&inode_table[i], 0, sizeof(struct inode)); /* super_block[] */ struct super_block * sb = super_block; for (; sb < &super_block[NR_SUPER_BLOCK]; sb++) sb->sb_dev = NO_DEV; /* open the device: hard disk */ MESSAGE driver_msg; driver_msg.type = DEV_OPEN; driver_msg.DEVICE = MINOR(ROOT_DEV); assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); /* make FS */ mkfs(); /* load super block of ROOT */ read_super_block(ROOT_DEV); sb = get_super_block(ROOT_DEV); assert(sb->magic == MAGIC_V1); root_inode = get_inode(ROOT_DEV, ROOT_INODE); }
// Return a pointer to an inode given its number. In a real filesystem, this // would require finding the correct block group, but you may assume it's in the // first one. struct ext2_inode * get_inode(void * fs, __u32 inode_num) { struct ext2_super_block * superBlock = get_super_block(fs); // superBlock->s_inodes_per_group = 0, we're assuming only one block group so inode_num-1 is index into inode table // hardcode 0 b/c assume only one block group struct ext2_group_desc * blockGroupDescriptor = get_block_group(fs, 0); struct ext2_inode * startOfINodeTable = (struct ext2_inode *) get_block(fs, blockGroupDescriptor->bg_inode_table); return startOfINodeTable + inode_num - 1; }
// Return a pointer to an inode given its number. In a real filesystem, this // would require finding the correct block group, but you may assume it's in the // first one. struct ext2_inode * get_inode(void * fs, __u32 inode_num) { struct ext2_super_block* s = get_super_block(fs); __u32 inode_per_group = EXT2_INODES_PER_GROUP(s); __u32 group_offset = (inode_num - 1) / inode_per_group; __u32 inode_offset = (inode_num - 1) % inode_per_group; __u32 inode_table_block = get_block_group(fs, group_offset)->bg_inode_table; return get_block(fs, inode_table_block) + inode_offset * EXT2_INODE_SIZE(s); }
// Return a pointer to an inode given its number. In a real filesystem, this // would require finding the correct block group, but you may assume it's in the // first one. struct ext2_inode * get_inode(void * fs, __u32 inode_num) { // Get the address of the block group descriptor. struct ext2_group_desc * group_desc_ptr = get_block_group(fs, 0); // Get the address of the inode table. void * inode_tbl_ptr = get_block(fs, group_desc_ptr->bg_inode_table); // Calculate the address of the inode. return inode_tbl_ptr + (inode_num - 1) * EXT2_INODE_SIZE(get_super_block(fs)); }
// Return a pointer to the first block group descriptor in a filesystem. Real // ext2 filesystems will have several of these, but, for simplicity, we will // assume there is only one. struct ext2_group_desc * get_block_group(void * fs, __u32 block_group_num) { // return the pointer to block 2, right after the super block. if (block_group_num == 0) { return (void*)get_super_block(fs) + SUPERBLOCK_SIZE; } else { return NULL; } }
// Return a pointer to the first block group descriptor in a filesystem. Real // ext2 filesystems will have several of these, but, for simplicity, we will // assume there is only one. struct ext2_group_desc * get_block_group(void * fs, __u32 block_group_num) { struct ext2_super_block * superBlock = get_super_block(fs); // get pointer to start of block group descriptor table // added 2 to get it to work, thought it should be 1 !!!? __u32 blockGroupDescriptorFirstBlock = superBlock->s_first_data_block + 2; return (struct ext2_group_desc *) get_block(fs, blockGroupDescriptorFirstBlock); // didn't add offset for block_group_num b/c assumption that only one block group }
struct m_inode *new_inode( int dev, int size ) { struct m_super_block *sb; struct d_block_table_entry *bt; struct m_inode *inode = NULL; if( (sb=get_super_block(dev)) == NULL ) panic("new_inode with unknow device!\n"); if( (bt=get_block_table(dev, size, 0)) == NULL ) panic("new_inode not find block table!\n"); inode = alloc_memery_inode(); set_imap_first_zero( bt, inode ); return inode; }
void dump_super_block(dev_t dev) { const SuperBlock *sb = get_super_block(dev); printk("Super Block:\n"); printk("sb_magic %x\n", sb->sb_magic); printk("sb_inodes %x\n", sb->sb_inodes); printk("sb_zones %x\n", sb->sb_zones); printk("sb_imap_blocks %x\n", sb->sb_imap_blocks); printk("sb_zmap_blocks %x\n", sb->sb_zmap_blocks); printk("sb_first_datazone %x\n", sb->sb_first_datazone); printk("sb_log_zone_size %x\n", sb->sb_log_zone_size); }
void free_super_block( int dev ) { struct m_super_block *psb; if( dev == ROOT_DEV ) { printk("root diskette change!\n"); } psb = get_super_block( dev ); if( psb != NULL ) { psb->sb_dev = NO_DEV; } }
PUBLIC struct inode *get_inode(int dev, int num) { struct inode *q = 0; /* 第 0 号 inode 为系统保留 */ if (num == 0) return 0; /* 先在内存中的 inode_table 里查找 */ for (struct inode *p = &inode_table[0]; p < &inode_table[NR_INODE]; p++) { if (p->i_cnt) { /* 如果找到了就直接返回 */ if ((p->i_dev == dev) && (p->i_num == num)) { p->i_cnt++; return p; } } else if (!q) q = p; } /* inode_table 已经满员了 */ if (!q) panic("the inode table is full"); /* 找到第 num 个 inode 所在的扇区 */ struct super_block *sb = get_super_block(dev); int blk_nr = 1 + 1 // boot sector + super block + sb->nr_imap_sects // + inode map + sb->nr_smap_sects // + sector map + ((num - 1) / (SECTOR_SIZE / INODE_SIZE)); /* 读取这个扇区然后找到第 num 个 inode */ RD_SECT(dev, blk_nr); struct inode *pinode = (struct inode *)((u8 *)fsbuf + ((num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE); /* 准备一个新的 inode */ q->i_mode = pinode->i_mode; q->i_size = pinode->i_size; q->i_start_sect = pinode->i_start_sect; q->i_nr_sects = pinode->i_nr_sects; q->i_dev = dev; q->i_num = num; q->i_cnt = 1; return q; }
static struct d_block_table_entry *get_block_table_from_nr( int dev, int nr ) { struct m_super_block *sb; struct d_block_table_entry *bt; int i; if( (sb=get_super_block(dev)) == NULL ) panic("new_inode with unknow device!\n"); bt = sb->p_block_table; for( i=0; i<NR_BLOCK_TABLE_ENTRY; i++,bt++ ) { if( bt->first_inode_num <= nr && nr < bt->first_inode_num + bt->inode_count ) return bt; } return NULL; }
//when inode is changed , write it to disk void sync_inode(struct inode *p) { struct inode *pinode; struct super_block * get_super_block(int dev); struct super_block *sb = get_super_block(p->i_dev); int blk_nr = 2+sb->nr_imap_sects + sb->nr_smap_sects+ ((p->i_num-1)/(SECTOR_SIZE /INODE_SIZE));//inode_nr==0 is not used RD_SECT(p->i_dev, blk_nr); pinode = (struct inode *)((t_8*)fsbuf + ((p->i_num-1)%(SECTOR_SIZE/INODE_SIZE)) *INODE_SIZE); pinode->i_mode = p->i_mode; pinode->i_size = p->i_size; pinode->i_start_sect = p->i_start_sect; pinode->i_nr_sects = p->i_nr_sects; WR_SECT(p->i_dev, blk_nr); }
/** * Allocate a bit in sector-map. * * @param dev In which device the sector-map is located. * @param nr_sects_to_alloc How many sectors are allocated. * * @return The 1st sector nr allocated. *****************************************************************************/ PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc) { /* int nr_sects_to_alloc = NR_DEFAULT_FILE_SECTS; */ int i; /* sector index */ int j; /* byte index */ int k; /* bit index */ struct super_block * sb = get_super_block(dev); int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; int free_sect_nr = 0; for (i = 0; i < sb->nr_smap_sects; i++) { /* smap_blk0_nr + i : current sect nr. */ RD_SECT(dev, smap_blk0_nr + i); /* byte offset in current sect */ for (j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) { k = 0; if (!free_sect_nr) { /* loop until a free bit is found */ if (fsbuf[j] == 0xFF) continue; for (; ((fsbuf[j] >> k) & 1) != 0; k++) {} free_sect_nr = (i * SECTOR_SIZE + j) * 8 + k - 1 + sb->n_1st_sect; } for (; k < 8; k++) { /* repeat till enough bits are set */ assert(((fsbuf[j] >> k) & 1) == 0); fsbuf[j] |= (1 << k); if (--nr_sects_to_alloc == 0) break; } } if (free_sect_nr) /* free bit found, write the bits to smap */ WR_SECT(dev, smap_blk0_nr + i); if (nr_sects_to_alloc == 0) break; } assert(nr_sects_to_alloc == 0); return free_sect_nr; }
/** * <Ring 1> Write the inode back to the disk. Commonly invoked as soon as the * inode is changed. * * @param p I-node ptr. *****************************************************************************/ PUBLIC void sync_inode(struct inode * p) { struct inode * pinode; struct super_block * sb = get_super_block(p->i_dev); int blk_nr = 1 + 1 + sb->nr_imap_sects + sb->nr_smap_sects + ((p->i_num - 1) / (SECTOR_SIZE / INODE_SIZE)); RD_SECT(p->i_dev, blk_nr); pinode = (struct inode*)((u8*)fsbuf + (((p->i_num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE)); pinode->i_mode = p->i_mode; pinode->i_size = p->i_size; pinode->i_start_sect = p->i_start_sect; pinode->i_nr_sects = p->i_nr_sects; WR_SECT(p->i_dev, blk_nr); }
/************************************************************************************************** * get_inode ************************************************************************************************** * <Ring 1> Get the inode pointer of given inode nr. A cache 'inode_table[]' is maintained to make * things faster. If the inode requested is already there, just return it. Otherwise the inode * will be read from the disk. * * @param dev Device nr. * @param num Inode nr. * * @return The inode pointer requested. *************************************************************************************************/ PUBLIC struct inode* get_inode(int dev, int num){ if(num == 0){ return 0; } struct inode* p; struct inode* q = 0; for(p=&inode_table[0]; p<&inode_table[NR_INODE]; p++){ if(p->i_cnt){ /* not a free slot */ if((p->i_dev == dev) && (p->i_num == num)){ /* this is the inode we want */ p->i_cnt++; return p; } }else{ /* a free slot */ if(!q){ /* q hasn't been assigned yet */ q = p; /* q <- the 1st free slot */ } } } if(!q){ panic("the inode table is full"); } q->i_dev = dev; q->i_num = num; q->i_cnt = 1; struct super_block* sb = get_super_block(dev); int nr_blk = 1 + 1 + sb->nr_imap_sects + sb->nr_smap_sects + ((num - 1) / (SECTOR_SIZE / INODE_SIZE)); RD_SECT(dev, nr_blk); struct inode* pinode = (struct inode*) ((u8*)fsbuf + ((num - 1) % (SECTOR_SIZE / INODE_SIZE)) * INODE_SIZE); q->i_mode = pinode->i_mode; q->i_size = pinode->i_size; q->i_start_sect = pinode->i_start_sect; q->i_nr_sects = pinode->i_nr_sects; return q; }
void mount_root( void ) { int i; struct m_super_block *p; if( 64 != sizeof( struct d_inode )) panic(" bad inode size!\n"); for( i=0; i< NR_FILE_DESC; i++ ) file_desc_table[i].fd_count = 0; for( p=super_block_table; p<super_block_table+NR_SUPER_BLOCK; p++ ) { memset( p, 0, sizeof(struct m_super_block) ); } read_super_block( ROOT_DEV ); if( !( p = get_super_block(ROOT_DEV)) ) panic("unable to mount root!\n"); read_block_table( p ); }
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc) { int i, j, k; assert(dev == ROOT_DEV); assert(nr_sects_to_alloc == NR_DEFAULT_FILE_SECTS); struct super_block* sb = get_super_block(dev); assert(sb -> nr_smap_sects); int smap_blk0_nr = 2 + sb -> nr_imap_sects; int free_sect_nr = 0; for (i=0; i<sb -> nr_smap_sects; i++) { RD_SECT(dev, smap_blk0_nr + i); for (j=0; j<SECTOR_SIZE && nr_sects_to_alloc>0; j++) { k = 0; if(!free_sect_nr) { /* 找到第一个空闲的扇区 */ /* 由于文件最大长度固定,并不需要考虑空洞,找到就可以了 */ if (fsbuf[j] == 0xFF) continue; for(; (fsbuf[j] & (1<<k)) != 0; k++) ; free_sect_nr = (i*SECTOR_SIZE + j) * 8 + k - 1 + sb -> n_1st_sect; } for(; k<8; k++) { assert(((fsbuf[j] >> k) & 1) == 0); fsbuf[j] |= 1<<k; if (--nr_sects_to_alloc == 0) break; } } if (free_sect_nr) WR_SECT(dev, smap_blk0_nr+i); if (nr_sects_to_alloc == 0) break; } if (nr_sects_to_alloc != 0) { panic("Don't have enough space.\n"); } return free_sect_nr; }
int display_super_block(void) { //Retrieve the super block superblock* super = get_super_block(); if(super == NULL) { return 0; } //Display the super block printf("size of disk, %d\n", super->size_of_disk); printf("block size, %d\n", super->block_size); printf("free_block_list, %d\n", super->free_block_list); printf("root dir, %d\n", super->root_dir); printf("device id, %d\n", super->device_id); return 1; }
/************************************************************************************************** * alloc_smap_bit ************************************************************************************************** * Allocate a bit in sector-map. * * @param dev In which device the sector-map is located. * @param nr_sects_to_alloc How many sectors are allocated. * * @return The 1st sector nr allocated. *************************************************************************************************/ PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc){ int i, j, k; /* i: sector index j: byte index k: bit index */ int nr_free_sect = 0; struct super_block* sb = get_super_block(dev); int nr_smap_blk0 = 1 + 1 + sb->nr_imap_sects; for(i=0; i<sb->nr_smap_sects; i++){ RD_SECT(dev, nr_smap_blk0 + i); for(j=0; j<SECTOR_SIZE && nr_sects_to_alloc > 0; j++){ k = 0; if(!nr_free_sect){ /* loop untill a free bit is found. */ if(fsbuf[j] == 0xff){ continue; } for(; ((fsbuf[j] >> k) & 1) != 0; k++){} nr_free_sect = (i * SECTOR_SIZE + j) * 8 + k - 1 + sb->n_1st_sect; } /* repeat till enough bits are set */ for(; k < 8; k++){ assert(((fsbuf[j] >> k) & 1) == 0); fsbuf[j] |= (1 << k); if(--nr_sects_to_alloc == 0){ break; } } } /* free bit was found, write the bit to smap */ if(nr_free_sect){ WR_SECT(dev, nr_smap_blk0 + i); } if(nr_sects_to_alloc == 0){ break; } } assert(nr_sects_to_alloc == 0); return nr_free_sect; }
//dev : //num :the no of inodg //return :the ptr to the inode struct inode * get_inode(int dev, int num) { // RD_SECT(dev , 0); if(num == 0) return 0; struct inode *p; struct inode *q =0; for(p = &inode_table[0]; p< &inode_table[NR_INODE]; p++) { if(p->i_cnt) { //we find it in inode table if((p->i_dev == dev )&& (p->i_num == num)) { p->i_cnt++; return p; } } else { //p->i_cnt==0 if(!q) { //the first cnt=0 inode q=p; } } } // if(!q) panic("the inode talbe is full\n"); q->i_dev = dev; q->i_num = num; q->i_cnt = 1; struct super_block * get_super_block(int dev); struct super_block *sb = get_super_block(dev); int blk_nr = 2+sb->nr_imap_sects + sb->nr_smap_sects+ ((num-1)/(SECTOR_SIZE /INODE_SIZE));//inode_nr==0 is not used RD_SECT(dev, blk_nr); struct inode *pinode= (struct inode *)((t_8 *)fsbuf + ((num-1)%(SECTOR_SIZE / INODE_SIZE))*INODE_SIZE ); q->i_mode = pinode->i_mode; q->i_size = pinode->i_size; q->i_start_sect = pinode ->i_start_sect; q->i_nr_sects = pinode->i_nr_sects; return q; }
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc) { struct super_block *sb = get_super_block(dev); int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; // boot sector + super block + inode map int free_sect_nr = 0; // 空闲 sector 起始号 for (int i = 0; i < sb->nr_smap_sects; i++) { // 逐扇区遍历 sector map RD_SECT(dev, smap_blk0_nr + i); for (int j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) { // 逐字节 int k = 0; if (!free_sect_nr) { if (fsbuf[j] == 0xFF) continue; for (; ((fsbuf[j] >> k) & 1) != 0; k++); // 逐位(一位代表一个扇区) free_sect_nr = (i * SECTOR_SIZE + j) * 8 + k - 1 + sb->n_1st_sect; } for (; k < 8; k++) { assert(((fsbuf[j] >> k) & 1) == 0); fsbuf[j] |= (1 << k); if (--nr_sects_to_alloc == 0) break; } } /* 将更新后的 sector map 扇区写入磁盘 */ if (free_sect_nr) WR_SECT(dev, smap_blk0_nr + i); if (nr_sects_to_alloc == 0) break; } assert(nr_sects_to_alloc == 0); return free_sect_nr; }
/** * Allocate a bit in sector-map. * * @param dev In which device the sector-map is located. * @param nr_sects_to_alloc How many sectors are allocated. * @param i_zone the zone of the inode * * @return The 1st sector nr allocated. *****************************************************************************/ PRIVATE int alloc_bit(int dev) { int i; /* sector index */ int j; /* byte index */ int k; /* bit index */ struct super_block * sb = get_super_block(dev); int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; int flag_bit_alloc = 0; int bit_alloc = 0; for (i = 0; i < sb->nr_smap_sects; i++) { /* smap_blk0_nr + i : current sect nr. */ RD_SECT(dev, smap_blk0_nr + i); /* byte offset in current sect */ for (j = 0; j < SECTOR_SIZE ; j++) { /* loop until a free bit is found */ if (fsbuf[j] != 0xFF) { k = 0; for (; ((fsbuf[j] >> k) & 1) != 0; k++) {} assert(((fsbuf[j] >> k) & 1) == 0); fsbuf[j] |= (1 << k); flag_bit_alloc = 1; //1 byte = 8 bit ~ stand for 8 sector bit_alloc = i * SECTOR_SIZE * 8 + j * 8 + k - 1 + sb->n_1st_sect; break; } } if (flag_bit_alloc) { /* free bit found, write the bits to smap */ WR_SECT(dev, smap_blk0_nr + i); break; } }
// Return a pointer to an inode given its number. In a real filesystem, this // would require finding the correct block group, but you may assume it's in the // first one. struct ext2_inode *get_inode(void *fs, __u32 inode_num) { struct ext2_group_desc *bg = get_block_group(fs, 0); // The inode table begins from 1. This is because an inode number 0 is always invalid. return get_block(fs, bg->bg_inode_table) + EXT2_INODE_SIZE(get_super_block(fs)) * (inode_num - 1); }
// Return the block size for a filesystem. __u32 get_block_size(void *fs) { return EXT2_BLOCK_SIZE(get_super_block(fs)); }
void print_fs(void) { int i, j; ino_t k; struct inode *inode2; unsigned short *usbuf; block_t b; struct direct *dir; assert(inodes_per_block * sizeof(*inode2) == block_size); if(!(inode2 = alloc_block())) err(1, "couldn't allocate a block of inodes"); assert(NR_DIR_ENTRIES(block_size)*sizeof(*dir) == block_size); if(!(dir = alloc_block())) err(1, "couldn't allocate a block of directory entries"); usbuf = alloc_block(); get_super_block(usbuf); printf("\nSuperblock: "); for (i = 0; i < 8; i++) printf("%06ho ", usbuf[i]); printf("\n "); for (i = 0; i < 8; i++) printf("%#04hX ", usbuf[i]); printf("\n "); for (i = 8; i < 15; i++) printf("%06ho ", usbuf[i]); printf("\n "); for (i = 8; i < 15; i++) printf("%#04hX ", usbuf[i]); get_block((block_t) INODE_MAP, usbuf); printf("...\nInode map: "); for (i = 0; i < 9; i++) printf("%06ho ", usbuf[i]); get_block((block_t) zone_map, usbuf); printf("...\nZone map: "); for (i = 0; i < 9; i++) printf("%06ho ", usbuf[i]); printf("...\n"); free(usbuf); usbuf = NULL; k = 0; for (b = inode_offset; k < nrinodes; b++) { get_block(b, inode2); for (i = 0; i < inodes_per_block; i++) { k = inodes_per_block * (int) (b - inode_offset) + i + 1; /* Lint but OK */ if (k > nrinodes) break; { if (inode2[i].i_mode != 0) { printf("Inode %3u: mode=", (unsigned)k); printf("%06o", (unsigned)inode2[i].i_mode); printf(" uid=%2d gid=%2d size=", (int)inode2[i].i_uid, (int)inode2[i].i_gid); printf("%6ld", (long)inode2[i].i_size); printf(" zone[0]=%u\n", (unsigned)inode2[i].i_zone[0]); } if ((inode2[i].i_mode & S_IFMT) == S_IFDIR) { /* This is a directory */ get_block(inode2[i].i_zone[0] << zone_shift, dir); for (j = 0; j < NR_DIR_ENTRIES(block_size); j++) if (dir[j].d_ino) printf("\tInode %2u: %s\n", (unsigned)dir[j].d_ino, dir[j].d_name); } } } } if (zone_shift) printf("%d inodes used. %u zones (%u blocks) used.\n", (int)next_inode-1, next_zone, next_zone*zone_per_block); else printf("%d inodes used. %u zones used.\n", (int)next_inode-1, next_zone); free(dir); free(inode2); }