*/
void fs_init(com32sys_t *regs)
{
- int blk_shift;
- const struct fs_ops *ops = (const struct fs_ops *)regs->eax.l;
+ uint8_t disk_devno = regs->edx.b[0];
+ uint8_t disk_cdrom = regs->edx.b[1];
+ sector_t disk_offset = regs->ecx.l | ((sector_t)regs->ebx.l << 32);
+ uint16_t disk_heads = regs->esi.w[0];
+ uint16_t disk_sectors = regs->edi.w[0];
+ int blk_shift = -1;
+ struct device *dev = NULL;
+ /* ops is a ptr list for several fs_ops */
+ const struct fs_ops **ops = (const struct fs_ops **)regs->eax.l;
- if (ops->fs_flags & FS_USEMEM)
- mem_init();
++ /* Initialize malloc() */
++ mem_init();
+
- /* set up the fs stucture */
- fs.fs_ops = ops;
- this_fs = &fs;
-
- /* this is a total hack... */
- if (ops->fs_flags & FS_NODEV)
- fs.fs_dev = NULL; /* Non-device filesystem */
- else
- fs.fs_dev = device_init(regs->edx.b[0], regs->edx.b[1], regs->ecx.l,
- regs->esi.w[0], regs->edi.w[0]);
+ while ((blk_shift < 0) && *ops) {
+ /* set up the fs stucture */
+ fs.fs_ops = *ops;
- /* invoke the fs-specific init code */
- blk_shift = fs.fs_ops->fs_init(&fs);
+ /*
+ * This boldly assumes that we don't mix FS_NODEV filesystems
+ * with FS_DEV filesystems...
+ */
+ if (fs.fs_ops->fs_flags & FS_NODEV) {
+ fs.fs_dev = NULL;
+ } else {
+ if (!dev)
+ dev = device_init(disk_devno, disk_cdrom, disk_offset,
+ disk_heads, disk_sectors);
+ fs.fs_dev = dev;
+ }
+ /* invoke the fs-specific init code */
+ blk_shift = fs.fs_ops->fs_init(&fs);
+ ops++;
+ }
if (blk_shift < 0) {
- printf("%s fs init error\n", fs.fs_ops->fs_name);
- for(;;) ; /* halt */
+ printf("No valid file system found!\n");
+ while (1)
+ ;
}
+ this_fs = &fs;
+
/* initialize the cache */
if (fs.fs_dev && fs.fs_dev->cache_data)
cache_init(fs.fs_dev, blk_shift);
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;
+ int blk_bits;
+ int db_count;
+ int i;
+ int desc_block;
+ char *desc_buffer;
+
/* 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;
- ClustByteShift = sb.s_log_block_size + 10;
- ClustSize = 1 << ClustByteShift;
- ClustShift = ClustByteShift - SECTOR_SHIFT;
-
- DescPerBlock = ClustSize >> ext2_group_desc_lg2size;
- InodePerBlock = ClustSize / sb.s_inode_size;
-
- SecPerClust = ClustSize >> SECTOR_SHIFT;
- ClustMask = SecPerClust - 1;
++
+ sbi = malloc(sizeof(*sbi));
+ if (!sbi) {
+ malloc_error("ext2_sb_info structure");
+ return -1;
+ }
+ fs->fs_info = sbi;
- PtrsPerBlock1 = 1 << (ClustByteShift - 2);
- PtrsPerBlock2 = 1 << ((ClustByteShift - 2) * 2);
- PtrsPerBlock3 = 1 << ((ClustByteShift - 2) * 3);
+ 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;
+
+ 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);
+ db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
+ EXT2_DESC_PER_BLOCK(fs);
+ sbi->s_inode_size = sb.s_inode_size;
+
+ /* read the descpritors */
+ desc_block = sb.s_first_data_block + 1;
+ desc_buffer = malloc(db_count * BLOCK_SIZE(fs));
+ if (!desc_buffer) {
+ malloc_error("desc_buffer");
+ return -1;
+ }
+ blk_bits = fs->block_shift - fs->sector_shift;
+ disk->rdwr_sectors(disk, desc_buffer, desc_block << blk_bits,
+ db_count << blk_bits, 0);
+ sbi->s_group_desc = malloc(sizeof(struct ext2_group_desc *)
+ * sbi->s_groups_count);
+ if (!sbi->s_group_desc) {
+ malloc_error("sbi->s_group_desc");
+ return -1;
+ }
+ for (i = 0; i < (int)sbi->s_groups_count; i++) {
+ sbi->s_group_desc[i] = (struct ext2_group_desc *)desc_buffer;
+ desc_buffer += sb.s_desc_size;
+ }
- return ClustByteShift;
+ return fs->block_shift;
}
const struct fs_ops ext2_fs_ops = {