]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Decrease stack usage in mdraid 0.9x.
authorVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 15:16:48 +0000 (16:16 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 15:16:48 +0000 (16:16 +0100)
We have only 92K of stack and using over 4K per frame is wasteful

* grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Allocate on heap
rather than stack.

ChangeLog
grub-core/disk/mdraid_linux.c

index 9e48e39322609aced23bdf539aa459dd33f6f477..0bbc2ebc36d1624d0e08b5ecb1f19f4318eacf34 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Decrease stack usage in mdraid 0.9x.
+
+       We have only 92K of stack and using over 4K per frame is wasteful
+
+       * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Allocate on heap
+       rather than stack.
+
 2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Decrease stack usage in BtrFS.
index f408fd37ef0be90a4eb35045df8a332cd30c4cd5..eb679f5ce1441f81aa6eba4ed82cc841d21c8bf4 100644 (file)
@@ -184,9 +184,10 @@ grub_mdraid_detect (grub_disk_t disk,
 {
   grub_disk_addr_t sector;
   grub_uint64_t size;
-  struct grub_raid_super_09 sb;
+  struct grub_raid_super_09 *sb = NULL;
   grub_uint32_t *uuid;
   grub_uint32_t level;
+  struct grub_diskfilter_vg *ret;
 
   /* The sector where the mdraid 0.90 superblock is stored, if available.  */
   size = grub_disk_get_size (disk);
@@ -195,27 +196,31 @@ grub_mdraid_detect (grub_disk_t disk,
     return NULL;
   sector = NEW_SIZE_SECTORS (size);
 
-  if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
+  sb = grub_malloc (sizeof (*sb));
+  if (!sb)
     return NULL;
 
+  if (grub_disk_read (disk, sector, 0, SB_BYTES, sb))
+    goto fail;
+
   /* Look whether there is a mdraid 0.90 superblock.  */
-  if (sb.md_magic != grub_cpu_to_md32_compile_time (SB_MAGIC))
+  if (sb->md_magic != grub_cpu_to_md32_compile_time (SB_MAGIC))
     /* not 0.9x raid.  */
-    return NULL;
+    goto fail;
 
-  if (sb.major_version != grub_cpu_to_md32_compile_time (0)
-      || sb.minor_version != grub_cpu_to_md32_compile_time (90))
+  if (sb->major_version != grub_cpu_to_md32_compile_time (0)
+      || sb->minor_version != grub_cpu_to_md32_compile_time (90))
     /* Unsupported version.  */
-    return NULL;
+    goto fail;
 
-  /* No need for explicit check that sb.size is 0 (unspecified) since
+  /* No need for explicit check that sb->size is 0 (unspecified) since
      0 >= non-0 is false.  */
-  if (((grub_disk_addr_t) grub_md_to_cpu32 (sb.size)) * 2 >= size)
-    return NULL;
+  if (((grub_disk_addr_t) grub_md_to_cpu32 (sb->size)) * 2 >= size)
+    goto fail;
 
   /* FIXME: Check the checksum.  */
 
-  level = grub_md_to_cpu32 (sb.level);
+  level = grub_md_to_cpu32 (sb->level);
   /* Multipath.  */
   if ((int) level == -4)
     level = 1;
@@ -225,37 +230,43 @@ grub_mdraid_detect (grub_disk_t disk,
     {
       grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                  "unsupported RAID level: %d", level);
-      return NULL;
+      goto fail;
     }
-  if (grub_md_to_cpu32 (sb.this_disk.number) == 0xffff
-      || grub_md_to_cpu32 (sb.this_disk.number) == 0xfffe)
+  if (grub_md_to_cpu32 (sb->this_disk.number) == 0xffff
+      || grub_md_to_cpu32 (sb->this_disk.number) == 0xfffe)
     /* Spares aren't implemented.  */
-    return NULL;
+    goto fail;
 
   uuid = grub_malloc (16);
   if (!uuid)
-    return NULL;
+    goto fail;
 
-  uuid[0] = grub_swap_bytes32 (sb.set_uuid0);
-  uuid[1] = grub_swap_bytes32 (sb.set_uuid1);
-  uuid[2] = grub_swap_bytes32 (sb.set_uuid2);
-  uuid[3] = grub_swap_bytes32 (sb.set_uuid3);
+  uuid[0] = grub_swap_bytes32 (sb->set_uuid0);
+  uuid[1] = grub_swap_bytes32 (sb->set_uuid1);
+  uuid[2] = grub_swap_bytes32 (sb->set_uuid2);
+  uuid[3] = grub_swap_bytes32 (sb->set_uuid3);
 
   *start_sector = 0;
 
   id->uuidlen = 0;
-  id->id = grub_md_to_cpu32 (sb.this_disk.number);
+  id->id = grub_md_to_cpu32 (sb->this_disk.number);
 
   char buf[32];
-  grub_snprintf (buf, sizeof (buf), "md%d", grub_md_to_cpu32 (sb.md_minor));
-  return grub_diskfilter_make_raid (16, (char *) uuid,
-                                   grub_md_to_cpu32 (sb.raid_disks), buf,
-                                   (sb.size) ? ((grub_disk_addr_t)
-                                                grub_md_to_cpu32 (sb.size)) * 2
-                                   : sector,
-                                   grub_md_to_cpu32 (sb.chunk_size) >> 9,
-                                   grub_md_to_cpu32 (sb.layout),
-                                   level);
+  grub_snprintf (buf, sizeof (buf), "md%d", grub_md_to_cpu32 (sb->md_minor));
+  ret = grub_diskfilter_make_raid (16, (char *) uuid,
+                                  grub_md_to_cpu32 (sb->raid_disks), buf,
+                                  (sb->size) ? ((grub_disk_addr_t)
+                                                grub_md_to_cpu32 (sb->size)) * 2
+                                  : sector,
+                                  grub_md_to_cpu32 (sb->chunk_size) >> 9,
+                                  grub_md_to_cpu32 (sb->layout),
+                                  level);
+  grub_free (sb);
+  return ret;
+
+ fail:
+  grub_free (sb);
+  return NULL;
 }
 
 static struct grub_diskfilter grub_mdraid_dev = {