=== modified file 'fs/minix.c'
--- fs/minix.c	2009-12-25 00:04:51 +0000
+++ fs/minix.c	2010-07-19 04:10:00 +0000
@@ -19,6 +19,7 @@
 
 #include <grub/err.h>
 #include <grub/file.h>
+#include <grub/partition.h>
 #include <grub/mm.h>
 #include <grub/misc.h>
 #include <grub/disk.h>
@@ -27,6 +28,7 @@
 
 #define GRUB_MINIX_MAGIC	0x137F
 #define GRUB_MINIX2_MAGIC	0x2468
+#define GRUB_MINIX3_MAGIC	0x4D5A
 #define GRUB_MINIX_MAGIC_30	0x138F
 #define GRUB_MINIX2_MAGIC_30	0x2478
 #define GRUB_MINIX_BSIZE	1024U
@@ -39,10 +41,15 @@
 #define GRUB_MINIX_IFLNK	0120000U
 
 #define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
-                           data->inode.  field : data->inode2.  field)
+                           data->inode.  field : \
+                           (data->version==2 ? \
+								data->inode2.  field : \
+								data->inode3.  field))
 #define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ?	\
                         grub_le_to_cpu##bits1 (data->inode.field) :		\
-                        grub_le_to_cpu##bits2 (data->inode2.field))
+                        (data->version == 2 ? \
+							grub_le_to_cpu##bits2 (data->inode2.field) : \
+							grub_le_to_cpu##bits2 (data->inode3.field)))
 #define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
 #define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
 #define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN		\
@@ -51,22 +58,28 @@
                         GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
 #define GRUB_MINIX_INODE_DINDIR_ZONE(data)					\
                         GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
-#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
 #define GRUB_MINIX_LOG2_ZONESZ	(GRUB_MINIX_LOG2_BSIZE				\
 				 + grub_le_to_cpu16 (sblock->log2_zone_size))
-#define GRUB_MINIX_ZONESZ	(GRUB_MINIX_BSIZE 				\
+#define GRUB_MINIX_ZONESZ	(blocksize 				\
 				 << grub_le_to_cpu16 (sblock->log2_zone_size))
 
 struct grub_minix_sblock
 {
-  grub_uint16_t inode_cnt;
+  grub_uint32_t inode_cnt;
   grub_uint16_t zone_cnt;
   grub_uint16_t inode_bmap_size;
   grub_uint16_t zone_bmap_size;
   grub_uint16_t first_data_zone;
   grub_uint16_t log2_zone_size;
+  grub_uint16_t pad;
   grub_uint32_t max_file_size;
+  grub_uint32_t zones;
   grub_uint16_t magic;
+  
+  /* V3 only fields */
+  grub_uint16_t pad2;
+  grub_uint16_t block_size;
+  grub_uint8_t disk_version; 
 };
 
 struct grub_minix_inode
@@ -99,12 +112,31 @@ struct grub_minix2_inode
 
 };
 
+struct grub_minix3_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint8_t gid;
+  grub_uint8_t pad_;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t dir_zones[7];
+  grub_uint32_t indir_zone;
+  grub_uint32_t double_indir_zone;
+  grub_uint32_t unused;
+
+};
+
 /* Information about a "mounted" minix filesystem.  */
 struct grub_minix_data
 {
   struct grub_minix_sblock sblock;
   struct grub_minix_inode inode;
   struct grub_minix2_inode inode2;
+  struct grub_minix3_inode inode3;
   int ino;
   int linknest;
   grub_disk_t disk;
@@ -113,7 +145,8 @@ struct grub_minix_data
 };
 
 static grub_dl_t my_mod;
-
+static unsigned int blocksize;
+
 static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
 					const char *path);
 
@@ -122,9 +155,23 @@ grub_minix_get_file_block (struct grub_m
 {
   struct grub_minix_sblock *sblock = &data->sblock;
   int indir;
-
+  unsigned int first_dbl_indir;
+  unsigned int indir_capacity;
   auto int grub_get_indir (int, int);
-
+  
+  if (data->version == 1)
+  {
+	indir_capacity=blocksize/2;
+  }
+  else if (data->version == 2)
+  {
+	indir_capacity=blocksize/4;
+  }
+  else
+  {
+	indir_capacity=blocksize/4;
+  }
+	
   /* Read the block pointer in ZONE, on the offset NUM.  */
   int grub_get_indir (int zone, int num)
     {
@@ -137,7 +184,7 @@ grub_minix_get_file_block (struct grub_m
 			  sizeof (grub_uint16_t), (char *) &indir16);
 	  return grub_le_to_cpu16 (indir16);
 	}
-      else
+      else if (data->version == 2)
 	{
 	  grub_uint32_t indir32;
 	  grub_disk_read (data->disk,
@@ -146,29 +193,39 @@ grub_minix_get_file_block (struct grub_m
 			  sizeof (grub_uint32_t), (char *) &indir32);
 	  return grub_le_to_cpu32 (indir32);
 	}
+      else
+	{
+	  grub_uint32_t indir32;
+	  grub_disk_read (data->disk,
+			  zone * (blocksize / GRUB_DISK_SECTOR_SIZE),
+			  sizeof (grub_uint32_t) * num,
+			  sizeof (grub_uint32_t), (char *) &indir32);
+	  return grub_le_to_cpu32 (indir32);
+	}
     }
 
+	
   /* Direct block.  */
   if (blk < 7)
     return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
-
   /* Indirect block.  */
-  blk -= 7;
-  if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+  first_dbl_indir=indir_capacity+7;
+  
+  if (blk < first_dbl_indir)
     {
+	  blk -= 7;
       indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
       return indir;
     }
 
   /* Double indirect block.  */
-  blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
-  if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
-      * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
+  blk -= first_dbl_indir;
+  if (blk < indir_capacity * indir_capacity)
     {
+		
       indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
-			      blk / GRUB_MINIX_ZONESZ);
-
-      indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
+			      blk / indir_capacity);
+      indir = grub_get_indir (indir, blk % indir_capacity);
 
       return indir;
     }
@@ -191,18 +248,19 @@ grub_minix_read_file (struct grub_minix_
   struct grub_minix_sblock *sblock = &data->sblock;
   int i;
   int blockcnt;
-
   /* Adjust len so it we can't read past the end of the file.  */
   if (len + pos > GRUB_MINIX_INODE_SIZE (data))
     len = GRUB_MINIX_INODE_SIZE (data) - pos;
 
-  blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
+  /*FIXME: compile error if following two statements combined */
+  blockcnt = (len + pos + blocksize - 1);
+  blockcnt /= blocksize;
 
-  for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
+  for (i = pos / blocksize; i < blockcnt; i++)
     {
       int blknr;
-      int blockoff = pos % GRUB_MINIX_BSIZE;
-      int blockend = GRUB_MINIX_BSIZE;
+      int blockoff = pos % blocksize;
+      int blockend = blocksize;
 
       int skipfirst = 0;
 
@@ -213,28 +271,33 @@ grub_minix_read_file (struct grub_minix_
       /* Last block.  */
       if (i == blockcnt - 1)
 	{
-	  blockend = (len + pos) % GRUB_MINIX_BSIZE;
+      /*FIXME: compile error if following two statements combined */
+	  blockend = (len + pos);
+	  blockend %= blocksize;
 
 	  if (!blockend)
-	    blockend = GRUB_MINIX_BSIZE;
+	    blockend = blocksize;
 	}
 
       /* First block.  */
-      if (i == (pos / (int) GRUB_MINIX_BSIZE))
+      if (i == (pos / (int) blocksize))
 	{
 	  skipfirst = blockoff;
 	  blockend -= skipfirst;
 	}
-
       data->disk->read_hook = read_hook;
-      grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
+      if(data->version<3)
+		grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
+		      skipfirst, blockend, buf);
+      else
+		grub_disk_read (data->disk, blknr * (data->sblock.block_size/GRUB_DISK_SECTOR_SIZE),
 		      skipfirst, blockend, buf);
 
       data->disk->read_hook = 0;
       if (grub_errno)
 	return -1;
 
-      buf += GRUB_MINIX_BSIZE - skipfirst;
+      buf += blocksize - skipfirst;
     }
 
   return len;
@@ -250,17 +313,17 @@ grub_minix_read_inode (struct grub_minix
 
   /* Block in which the inode is stored.  */
   int block;
+  if(ino==0) return GRUB_ERR_BAD_ARGUMENT;
   data->ino = ino;
-
   /* The first inode in minix is inode 1.  */
   ino--;
 
-  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
-	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
-	   << GRUB_MINIX_LOG2_BSIZE);
-
   if (data->version == 1)
     {
+	  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
+	   << GRUB_MINIX_LOG2_BSIZE);
+	   
       block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
       int offs = (ino % (GRUB_DISK_SECTOR_SIZE
 			 / sizeof (struct grub_minix_inode))
@@ -269,8 +332,11 @@ grub_minix_read_inode (struct grub_minix
       grub_disk_read (data->disk, block, offs,
 		      sizeof (struct grub_minix_inode), &data->inode);
     }
-  else
+  else if (data->version == 2)
     {
+	  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
+	   << GRUB_MINIX_LOG2_BSIZE);
       block += ino / (GRUB_DISK_SECTOR_SIZE
 		      / sizeof (struct grub_minix2_inode));
       int offs = (ino
@@ -280,7 +346,20 @@ grub_minix_read_inode (struct grub_minix
       grub_disk_read (data->disk, block, offs,
 		      sizeof (struct grub_minix2_inode),&data->inode2);
     }
-
+  else
+  {
+	  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
+	   *(sblock->block_size/GRUB_DISK_SECTOR_SIZE));
+	  block += ino / (GRUB_DISK_SECTOR_SIZE
+		      / sizeof (struct grub_minix3_inode));
+      int offs = (ino
+		  % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix3_inode))
+		  * sizeof (struct grub_minix3_inode));
+	
+      grub_disk_read (data->disk, block, offs,
+		      sizeof (struct grub_minix3_inode),&data->inode3);
+  }
   return GRUB_ERR_NONE;
 }
 
@@ -348,16 +427,17 @@ grub_minix_find_file (struct grub_minix_
 
   do
     {
-      grub_uint16_t ino;
+      grub_uint32_t ino;
+      unsigned int ino_size=data->version<3 ? 2 : 4;
       char filename[data->filename_size + 1];
 
       if (grub_strlen (name) == 0)
-	return GRUB_ERR_NONE;
+	    return GRUB_ERR_NONE;
 
-      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos, ino_size,
 				(char *) &ino) < 0)
 	return grub_errno;
-      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos + ino_size,
 				data->filename_size, (char *) filename)< 0)
 	return grub_errno;
 
@@ -399,7 +479,7 @@ grub_minix_find_file (struct grub_minix_
 	  continue;
 	}
 
-      pos += sizeof (ino) + data->filename_size;
+      pos += ino_size + data->filename_size;
     } while (pos < GRUB_MINIX_INODE_SIZE (data));
 
   grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
@@ -433,6 +513,11 @@ grub_minix_mount (grub_disk_t disk)
       data->version = 2;
       data->filename_size = 14;
     }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX3_MAGIC)
+    {
+      data->version = 3;
+      data->filename_size = 60;
+    }
   else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
     {
       data->version = 1;
@@ -448,7 +533,12 @@ grub_minix_mount (grub_disk_t disk)
 
   data->disk = disk;
   data->linknest = 0;
+  /* set global block size var for mounted fs */
+  if(data->version==3)
+	blocksize=data->sblock.block_size;
+  else
+	blocksize=GRUB_MINIX_BSIZE;
   return data;
 
  fail:
@@ -488,35 +578,38 @@ grub_minix_dir (grub_device_t device, co
 
   while (pos < GRUB_MINIX_INODE_SIZE (data))
     {
-      grub_uint16_t ino;
+      grub_uint32_t ino;
+      /* Inode type is different in size between v2 and v3 */
+      unsigned int ino_size=data->version<3 ? 2 : 4;
       char filename[data->filename_size + 1];
       int dirino = data->ino;
       struct grub_dirhook_info info;
       grub_memset (&info, 0, sizeof (info));
 
 
-      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos, ino_size,
 				(char *) &ino) < 0)
 	return grub_errno;
-
-      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos + ino_size,
 				data->filename_size,
 				(char *) filename) < 0)
 	return grub_errno;
       filename[data->filename_size] = '\0';
-
-      /* The filetype is not stored in the dirent.  Read the inode to
-	 find out the filetype.  This *REALLY* sucks.  */
+	if(ino)
+	{
+	  /* It's a valid dirent only when ino > 0, check before calling the hook.
+         The filetype is not stored in the dirent.  Read the inode to
+	     find out the filetype.  This *REALLY* sucks.  */
       grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
       info.dir = ((GRUB_MINIX_INODE_MODE (data)
 		   & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
       if (hook (filename, &info) ? 1 : 0)
 	break;
-
+	
       /* Load the old inode back in.  */
       grub_minix_read_inode (data, dirino);
-
-      pos += sizeof (ino) + data->filename_size;
+	}
+      pos += ino_size + data->filename_size;
     }
 
  fail:
@@ -582,14 +675,6 @@ grub_minix_close (grub_file_t file)
   return GRUB_ERR_NONE;
 }
 
-
-static grub_err_t
-grub_minix_label (grub_device_t device __attribute ((unused)),
-		char **label __attribute ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-
 
 static struct grub_fs grub_minix_fs =
   {
@@ -598,7 +683,7 @@ static struct grub_fs grub_minix_fs =
     .open = grub_minix_open,
     .read = grub_minix_read,
     .close = grub_minix_close,
-    .label = grub_minix_label,
+    .label = 0,
     .next = 0
   };
 

=== modified file 'partmap/msdos.c'
--- partmap/msdos.c	2010-03-26 14:44:13 +0000
+++ partmap/msdos.c	2010-07-19 04:12:17 +0000
@@ -37,7 +37,6 @@ pc_partition_map_iterate (grub_disk_t di
   int labeln = 0;
   grub_disk_addr_t lastaddr;
   grub_disk_addr_t ext_offset;
-
   p.offset = 0;
   ext_offset = 0;
   p.number = -1;
@@ -51,7 +50,6 @@ pc_partition_map_iterate (grub_disk_t di
     {
       int i;
       struct grub_msdos_partition_entry *e;
-
       /* Read the MBR.  */
       if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
 	goto finish;
@@ -76,14 +74,16 @@ pc_partition_map_iterate (grub_disk_t di
 	if (mbr.entries[i].flag & 0x7f)
 	  return grub_error (GRUB_ERR_BAD_PART_TABLE, "bad boot flag");
 
+	
       /* Analyze DOS partitions.  */
       for (p.index = 0; p.index < 4; p.index++)
 	{
 	  e = mbr.entries + p.index;
 
 	  p.start = p.offset + grub_le_to_cpu32 (e->start);
+	  if(disk->partition && e->type == GRUB_PC_PARTITION_TYPE_LINUX_MINIX)
+		p.start -= disk->partition->start;
 	  p.len = grub_le_to_cpu32 (e->length);
-
 	  grub_dprintf ("partition",
 			"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
 			p.index, e->flag, e->type,
@@ -93,13 +93,11 @@ pc_partition_map_iterate (grub_disk_t di
 	  /* If this is a GPT partition, this MBR is just a dummy.  */
 	  if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
 	    return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
-
 	  /* If this partition is a normal one, call the hook.  */
 	  if (! grub_msdos_partition_is_empty (e->type)
 	      && ! grub_msdos_partition_is_extended (e->type))
 	    {
 	      p.number++;
-
 	      if (hook (disk, &p))
 		return grub_errno;
 	    }

