
From: Stephen Warren swarren@nvidia.com
The existing get_device_and_partition() bootable search loop attempts to save the current best known partition in variable best_part. However, it's actually just saving a copy of the (static) "info" variable, and hence ends up not doing anything much useful if no bootable partition is found. Fix this by reworking the loop to:
a) When reading information about a partition, always read into the caller-supplied buffer; that way, if we find a bootable partition, there's no need to copy any information. b) Save the first known valid partition's structure content rather than pointer in the search loop, and restore the structure content rather than the pointer when the loop exits.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v3: New patch. --- disk/part.c | 38 +++++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/disk/part.c b/disk/part.c index 6caf6d2..277a243 100644 --- a/disk/part.c +++ b/disk/part.c @@ -447,7 +447,7 @@ int get_device_and_partition(const char *ifname, const char *dev_str, int p; int part = 0; char *part_str; - disk_partition_t *best_part = NULL; + disk_partition_t tmpinfo;
if (dev_str) dev = simple_strtoul(dev_str, &ep, 16); @@ -483,24 +483,44 @@ int get_device_and_partition(const char *ifname, const char *dev_str, part = (int)simple_strtoul(++part_str, NULL, 16); ret = get_partition_info(desc, part, info); } else { - /* find the first bootable partition. If none are bootable, - * fall back to the first valid partition */ + /* + * Find the first bootable partition. + * If none are bootable, fall back to the first valid partition. + */ for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { - ret = get_partition_info(desc, p, info); + ret = get_partition_info(*dev_desc, p, info); if (ret) continue;
- if (!best_part || info->bootable) { - best_part = info; + /* + * First valid partition, or new better partition? + * If so, save partition ID. + */ + if (!part || info->bootable) part = p; - }
+ /* Best possible partition? Stop searching. */ if (info->bootable) break; + + /* + * We now need to search further for best possible. + * If we what we just queried was the best so far, + * save the info since we over-write it next loop. + */ + if (part == p) + tmpinfo = *info; } - info = best_part; - if (part) + /* If we found any acceptable partition */ + if (part) { + /* + * If we searched all possible partition IDs, + * return the first valid partition we found. + */ + if (p == MAX_SEARCH_PARTITIONS + 1) + *info = tmpinfo; ret = 0; + } } if (ret) { printf("** Invalid partition %d, use `dev[:part]' **\n", part);