/* * init. the fs meta data, return the block size bits. */ static int ext2_fs_init(struct fs_info *fs) { struct disk *disk = fs->fs_dev->disk; struct ext2_sb_info *sbi; struct ext2_super_block sb; struct cache *cs; /* read the super block */ disk->rdwr_sectors(disk, &sb, 2, 2, 0); /* check if it is ext2, since we also support btrfs now */ if (sb.s_magic != EXT2_SUPER_MAGIC) return -1; sbi = malloc(sizeof(*sbi)); if (!sbi) { malloc_error("ext2_sb_info structure"); return -1; } fs->fs_info = sbi; if (sb.s_magic != EXT2_SUPER_MAGIC) { printf("ext2 mount error: it's not a EXT2/3/4 file system!\n"); return 0; } fs->sector_shift = disk->sector_shift; fs->block_shift = sb.s_log_block_size + 10; fs->sector_size = 1 << fs->sector_shift; fs->block_size = 1 << fs->block_shift; sbi->s_inodes_per_group = sb.s_inodes_per_group; sbi->s_blocks_per_group = sb.s_blocks_per_group; sbi->s_inodes_per_block = BLOCK_SIZE(fs) / sb.s_inode_size; if (sb.s_desc_size < sizeof(struct ext2_group_desc)) sb.s_desc_size = sizeof(struct ext2_group_desc); sbi->s_desc_per_block = BLOCK_SIZE(fs) / sb.s_desc_size; sbi->s_groups_count = (sb.s_blocks_count - sb.s_first_data_block + EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs); sbi->s_first_data_block = sb.s_first_data_block; sbi->s_inode_size = sb.s_inode_size; /* Volume UUID */ memcpy(sbi->s_uuid, sb.s_uuid, sizeof(sbi->s_uuid)); /* Initialize the cache, and force block zero to all zero */ cache_init(fs->fs_dev, fs->block_shift); cs = _get_cache_block(fs->fs_dev, 0); memset(cs->data, 0, fs->block_size); cache_lock_block(cs); return fs->block_shift; }
/* * Check for a particular BLOCK in the block cache, * and if it is already there, just do nothing and return; * otherwise load it from disk and update the LRU link. * Return the data pointer. */ const void *get_cache(struct device *dev, block_t block) { struct cache *cs; cs = _get_cache_block(dev, block); if (cs->block != block) { cs->block = block; getoneblk(dev->disk, cs->data, block, dev->cache_block_size); } return cs->data; }