From 0d31250038439857332f9408e7304698ab171e3c Mon Sep 17 00:00:00 2001 From: davem Date: Fri, 24 Apr 2009 12:04:10 +0000 Subject: [PATCH] Avoiding openning same device multiple times in device iterator. * kern/device.c (grub_device_iterate): Define struct part_ent, and use it to build a list of partitions in interate_disk() and iterate_partition(). --- ChangeLog | 8 +++++++ kern/device.c | 58 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 55d4f3779..d32bc2dfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-04-24 David S. Miller + + Avoiding openning same device multiple times in device iterator. + + * kern/device.c: (grub_device_iterate): Define struct part_ent, + and use it to build a list of partitions in interate_disk() and + iterate_partition(). + 2009-04-23 David S. Miller * kern/sparc64/ieee1275/openfw.c: Unused, delete. diff --git a/kern/device.c b/kern/device.c index 60f25c192..184c3a27f 100644 --- a/kern/device.c +++ b/kern/device.c @@ -83,6 +83,12 @@ grub_device_iterate (int (*hook) (const char *name)) auto int iterate_partition (grub_disk_t disk, const grub_partition_t partition); + struct part_ent + { + struct part_ent *next; + char *name; + } *ents = NULL; + int iterate_disk (const char *disk_name) { grub_device_t dev; @@ -95,11 +101,28 @@ grub_device_iterate (int (*hook) (const char *name)) return 0; if (dev->disk && dev->disk->has_partitions) - if (grub_partition_iterate (dev->disk, iterate_partition)) - { - grub_device_close (dev); - return 1; - } + { + struct part_ent *p; + int ret = 0; + + (void) grub_partition_iterate (dev->disk, iterate_partition); + grub_device_close (dev); + + p = ents; + ents = NULL; + while (p != NULL) + { + struct part_ent *next = p->next; + + if (!ret) + ret = hook (p->name); + grub_free (p->name); + grub_free (p); + p = next; + } + + return ret; + } grub_device_close (dev); return 0; @@ -108,27 +131,32 @@ grub_device_iterate (int (*hook) (const char *name)) int iterate_partition (grub_disk_t disk, const grub_partition_t partition) { char *partition_name; - char *device_name; - int ret; + struct part_ent *p; partition_name = grub_partition_get_name (partition); if (! partition_name) return 1; - - device_name = grub_malloc (grub_strlen (disk->name) + 1 - + grub_strlen (partition_name) + 1); - if (! device_name) + + p = grub_malloc (sizeof (*p)); + if (!p) + return 1; + + p->name = grub_malloc (grub_strlen (disk->name) + 1 + + grub_strlen (partition_name) + 1); + if (! p->name) { + grub_free (p); grub_free (partition_name); return 1; } - grub_sprintf (device_name, "%s,%s", disk->name, partition_name); + grub_sprintf (p->name, "%s,%s", disk->name, partition_name); grub_free (partition_name); - ret = hook (device_name); - grub_free (device_name); - return ret; + p->next = ents; + ents = p; + + return 0; } /* Only disk devices are supported at the moment. */