a5bd9f6
From 13d76e946f149e21c67938e7dadcbb3db9019b17 Mon Sep 17 00:00:00 2001
a5bd9f6
From: Andrey Borzenkov <arvidjaar@gmail.com>
a5bd9f6
Date: Mon, 25 Feb 2013 22:11:06 +0100
a5bd9f6
Subject: [PATCH 156/364] 	* Makefile.util.def: Add partmap/msdos.c to
a5bd9f6
 common library. 	* include/grub/msdos_partition.h: Add
a5bd9f6
 GRUB_PC_PARTITION_TYPE_LDM 	* grub-core/disk/ldm.c: Check for existence of
a5bd9f6
 	GRUB_PC_PARTITION_TYPE_LDM.
a5bd9f6
a5bd9f6
---
a5bd9f6
 ChangeLog                      |  7 +++++++
a5bd9f6
 Makefile.util.def              |  2 +-
a5bd9f6
 grub-core/disk/ldm.c           | 42 ++++++++++++++++++++++++++++++++++++++++--
a5bd9f6
 include/grub/msdos_partition.h |  1 +
a5bd9f6
 4 files changed, 49 insertions(+), 3 deletions(-)
a5bd9f6
a5bd9f6
diff --git a/ChangeLog b/ChangeLog
a5bd9f6
index ff5a558..107c049 100644
a5bd9f6
--- a/ChangeLog
a5bd9f6
+++ b/ChangeLog
a5bd9f6
@@ -1,3 +1,10 @@
a5bd9f6
+2013-02-25  Andrey Borzenkov <arvidjaar@gmail.com>
a5bd9f6
+
a5bd9f6
+	* Makefile.util.def: Add partmap/msdos.c to common library.
a5bd9f6
+	* include/grub/msdos_partition.h: Add GRUB_PC_PARTITION_TYPE_LDM
a5bd9f6
+	* grub-core/disk/ldm.c: Check for existence of
a5bd9f6
+	GRUB_PC_PARTITION_TYPE_LDM.
a5bd9f6
+
a5bd9f6
 2013-02-25  Vladimir Serbinenko  <phcoder@gmail.com>
a5bd9f6
 
a5bd9f6
 	* grub-core/normal/misc.c (grub_normal_print_device_info): Use KiB to display
a5bd9f6
diff --git a/Makefile.util.def b/Makefile.util.def
a5bd9f6
index 3ee5e4e..1ccf390 100644
a5bd9f6
--- a/Makefile.util.def
a5bd9f6
+++ b/Makefile.util.def
a5bd9f6
@@ -32,6 +32,7 @@ library = {
a5bd9f6
   common = grub-core/disk/ldm.c;
a5bd9f6
   common = grub-core/disk/diskfilter.c;
a5bd9f6
   common = grub-core/partmap/gpt.c;
a5bd9f6
+  common = grub-core/partmap/msdos.c;
a5bd9f6
 };
a5bd9f6
 
a5bd9f6
 library = {
a5bd9f6
@@ -110,7 +111,6 @@ library = {
a5bd9f6
   common = grub-core/partmap/acorn.c;
a5bd9f6
   common = grub-core/partmap/amiga.c;
a5bd9f6
   common = grub-core/partmap/apple.c;
a5bd9f6
-  common = grub-core/partmap/msdos.c;
a5bd9f6
   common = grub-core/partmap/sun.c;
a5bd9f6
   common = grub-core/partmap/plan.c;
a5bd9f6
   common = grub-core/partmap/dvh.c;
a5bd9f6
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
a5bd9f6
index b92433d..a2e26b2 100644
a5bd9f6
--- a/grub-core/disk/ldm.c
a5bd9f6
+++ b/grub-core/disk/ldm.c
a5bd9f6
@@ -22,6 +22,7 @@
a5bd9f6
 #include <grub/err.h>
a5bd9f6
 #include <grub/misc.h>
a5bd9f6
 #include <grub/diskfilter.h>
a5bd9f6
+#include <grub/msdos_partition.h>
a5bd9f6
 #include <grub/gpt_partition.h>
a5bd9f6
 #include <grub/i18n.h>
a5bd9f6
 
a5bd9f6
@@ -103,6 +104,37 @@ read_int (grub_uint8_t *in, grub_size_t s)
a5bd9f6
   return ret;
a5bd9f6
 }
a5bd9f6
 
a5bd9f6
+static int
a5bd9f6
+check_ldm_partition (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p, void *data)
a5bd9f6
+{
a5bd9f6
+  int *has_ldm = data;
a5bd9f6
+
a5bd9f6
+  if (p->number >= 4)
a5bd9f6
+    return 1;
a5bd9f6
+  if (p->msdostype == GRUB_PC_PARTITION_TYPE_LDM)
a5bd9f6
+    {
a5bd9f6
+      *has_ldm = 1;
a5bd9f6
+      return 1;
a5bd9f6
+    }
a5bd9f6
+  return 0;
a5bd9f6
+}
a5bd9f6
+
a5bd9f6
+static int
a5bd9f6
+msdos_has_ldm_partition (grub_disk_t dsk)
a5bd9f6
+{
a5bd9f6
+  grub_err_t err;
a5bd9f6
+  int has_ldm = 0;
a5bd9f6
+
a5bd9f6
+  err = grub_partition_msdos_iterate (dsk, check_ldm_partition, &has_ldm);
a5bd9f6
+  if (err)
a5bd9f6
+    {
a5bd9f6
+      grub_errno = GRUB_ERR_NONE;
a5bd9f6
+      return 0;
a5bd9f6
+    }
a5bd9f6
+
a5bd9f6
+  return has_ldm;
a5bd9f6
+}
a5bd9f6
+
a5bd9f6
 static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM;
a5bd9f6
 
a5bd9f6
 /* Helper for gpt_ldm_sector.  */
a5bd9f6
@@ -760,17 +792,20 @@ grub_ldm_detect (grub_disk_t disk,
a5bd9f6
 
a5bd9f6
   {
a5bd9f6
     int i;
a5bd9f6
+    int has_ldm = msdos_has_ldm_partition (disk);
a5bd9f6
     for (i = 0; i < 3; i++)
a5bd9f6
       {
a5bd9f6
 	grub_disk_addr_t sector = LDM_LABEL_SECTOR;
a5bd9f6
 	switch (i)
a5bd9f6
 	  {
a5bd9f6
 	  case 0:
a5bd9f6
+	    if (!has_ldm)
a5bd9f6
+	      continue;
a5bd9f6
 	    sector = LDM_LABEL_SECTOR;
a5bd9f6
 	    break;
a5bd9f6
 	  case 1:
a5bd9f6
 	    /* LDM is never inside a partition.  */
a5bd9f6
-	    if (disk->partition)
a5bd9f6
+	    if (!has_ldm || disk->partition)
a5bd9f6
 	      continue;
a5bd9f6
 	    sector = grub_disk_get_size (disk);
a5bd9f6
 	    if (sector == GRUB_DISK_SIZE_UNKNOWN)
a5bd9f6
@@ -871,6 +906,7 @@ int
a5bd9f6
 grub_util_is_ldm (grub_disk_t disk)
a5bd9f6
 {
a5bd9f6
   int i;
a5bd9f6
+  int has_ldm = msdos_has_ldm_partition (disk);
a5bd9f6
   for (i = 0; i < 3; i++)
a5bd9f6
     {
a5bd9f6
       grub_disk_addr_t sector = LDM_LABEL_SECTOR;
a5bd9f6
@@ -880,11 +916,13 @@ grub_util_is_ldm (grub_disk_t disk)
a5bd9f6
       switch (i)
a5bd9f6
 	{
a5bd9f6
 	case 0:
a5bd9f6
+	  if (!has_ldm)
a5bd9f6
+	    continue;
a5bd9f6
 	  sector = LDM_LABEL_SECTOR;
a5bd9f6
 	  break;
a5bd9f6
 	case 1:
a5bd9f6
 	  /* LDM is never inside a partition.  */
a5bd9f6
-	  if (disk->partition)
a5bd9f6
+	  if (!has_ldm || disk->partition)
a5bd9f6
 	    continue;
a5bd9f6
 	  sector = grub_disk_get_size (disk);
a5bd9f6
 	  if (sector == GRUB_DISK_SIZE_UNKNOWN)
a5bd9f6
diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h
a5bd9f6
index 1e9b65e..92f8539 100644
a5bd9f6
--- a/include/grub/msdos_partition.h
a5bd9f6
+++ b/include/grub/msdos_partition.h
a5bd9f6
@@ -43,6 +43,7 @@
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_FAT16_LBA	0xe
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED	0xf
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_PLAN9            0x39
a5bd9f6
+#define GRUB_PC_PARTITION_TYPE_LDM		0x42
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_EZD		0x55
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_MINIX		0x80
a5bd9f6
 #define GRUB_PC_PARTITION_TYPE_LINUX_MINIX	0x81
a5bd9f6
-- 
a5bd9f6
1.8.1.4
a5bd9f6