Hi,

This patch fix an issue in raid0. mdadm set the disk size field in
super block to 0 for raid0, so the size of device (md0) will be 0.
This patch fix this by calculating the size of (md0) when
array->disk_size is 0.

Another problem is actually caused by qemu, but as it's the main
testing platform, I add it here as well. For cdrom drive, the size is
not accurate. When raid.c scans a cdrom drive, it read beyond the cd
limit, which cause qemu to halt. This patch add a field size_invalid
in the disk structure, and raid use this to avoid scanning cdrom
drives.

2008-08-09  Bean  <[EMAIL PROTECTED]>

        * disk/i386/pc/biodisk.c (grub_biosdisk_open): Set size_invalid for
        cdrom drive.

        * disk.raid.c (grub_raid_open): Calculte the raid0 disk size if
        array->disk_size is 0.
        (grub_raid_scan_device): Skip drive where size_invalid is set.

        * include/grub/disk.h (grub_disk): New field size_invalid.

        * kern/disk.c (grub_disk_open): Initialize field size_invalid to 0.

-- 
Bean
diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c
index c8fd142..ff8eed4 100644
--- a/disk/i386/pc/biosdisk.c
+++ b/disk/i386/pc/biosdisk.c
@@ -121,6 +121,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
       data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
       data->sectors = 32;
       total_sectors = 9000000;  /* TODO: get the correct size.  */
+      disk->size_invalid = 1;
     }
   else if (drive & 0x80)
     {
diff --git a/disk/raid.c b/disk/raid.c
index 731bf1f..44a5cb2 100644
--- a/disk/raid.c
+++ b/disk/raid.c
@@ -113,7 +113,17 @@ grub_raid_open (const char *name, grub_disk_t disk)
     {
     case 0:
       /* FIXME: RAID0 disks can have different sizes! */
-      disk->total_sectors = array->total_devs * array->disk_size;
+      if (array->disk_size)
+        disk->total_sectors = array->total_devs * array->disk_size;
+      else
+        {
+          unsigned i;
+
+          disk->total_sectors = 0;
+          for (i = 0; i < array->total_devs; i++)
+            disk->total_sectors += array->device[i]->total_sectors;
+        }
+
       break;
 
     case 1:
@@ -364,6 +374,12 @@ grub_raid_scan_device (const char *name)
   if (!disk)
     return 0;
 
+  if (disk->size_invalid)
+    {
+      grub_disk_close (disk);
+      return 0;
+    }
+
   /* The sector where the RAID superblock is stored, if available. */
   size = grub_disk_get_size (disk);
   sector = GRUB_RAID_NEW_SIZE_SECTORS(size);
diff --git a/include/grub/disk.h b/include/grub/disk.h
index 049cc91..7248be6 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -93,6 +93,9 @@ struct grub_disk
   /* The underlying disk device.  */
   grub_disk_dev_t dev;
 
+  /* If total_sectors is invalid.  */
+  int size_invalid;
+
   /* The total number of sectors.  */
   grub_uint64_t total_sectors;
 
diff --git a/kern/disk.c b/kern/disk.c
index ed82506..ee35890 100644
--- a/kern/disk.c
+++ b/kern/disk.c
@@ -227,6 +227,7 @@ grub_disk_open (const char *name)
   disk->read_hook = 0;
   disk->partition = 0;
   disk->data = 0;
+  disk->size_invalid = 0;
   disk->name = grub_strdup (name);
   if (! disk->name)
     goto fail;
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to