Merge commit 'liu/master' into fsc
authorH. Peter Anvin <hpa@zytor.com>
Tue, 29 Dec 2009 01:38:48 +0000 (17:38 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 29 Dec 2009 01:38:48 +0000 (17:38 -0800)
Resolved Conflicts:
core/fs.c
core/fs/ext2/ext2.c

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1  2 
core/diskstart.inc
core/fs.c
core/fs/ext2/ext2.c
core/fs/pxe/pxe.c
core/include/fs.h

@@@ -411,6 -411,6 +411,7 @@@ getlinsec_cbios
  ;
  ; kaboom: write a message and bail out.
  ;
++              global kaboom
  disk_error:
  kaboom:
                xor si,si
diff --cc core/fs.c
+++ b/core/fs.c
@@@ -166,42 -235,30 +235,46 @@@ void close_file(com32sys_t *regs
   */
  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);
@@@ -702,28 -410,67 +410,71 @@@ static int ext2_load_config(void
  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 = {
Simple merge
@@@ -5,6 -5,6 +5,7 @@@
  #include <stdbool.h>
  #include <string.h>
  #include <com32.h>
++#include <stdio.h>
  #include "core.h"
  #include "disk.h"
  
@@@ -88,6 -141,20 +142,21 @@@ static inline bool not_whitespace(char 
    return (unsigned char)c > ' ';
  }
  
+ static inline void free_inode(struct inode * inode)
+ {
+     if (inode) {
+       if (inode->data)
+           free(inode->data);
+       free(inode);
+     }
+ }
+ static inline void malloc_error(char *obj)
+ {
+         printf("Out of memory: can't allocate memory for %s\n", obj);
++      kaboom();
+ }
  /* 
   * functions
   */