lkml.org 
[lkml]   [2010]   [Aug]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH RFC] efi: add and expose efi_partition_by_guid
(cc'ing Kay and quoting whole message for him)

Kay, you were talking about using GUID in GPT for finding out root
device and so on. Does this fit your use case too? If not it would
be nice to find out something which can be shared.

On 08/02/2010 09:17 PM, Will Drewry wrote:
> EFI's GPT partitioning scheme expects that all partitions have a unique
> identifiers. After initial partition scanning, this information is
> completely lost to the rest of the kernel.
>
> efi_partition_by_guid exposes GPT parsing support in a limited fashion
> to allow other portions of the kernel to map a partition from GUID to
> map.
>
> An alternate implementation (and more generic) would be to expose a function
> (efi_partition_walk) that iterates over the partition table providing access to
> each partitions information to a callback, much like device class iterators.
>
> The motivation for this change is the ability to have device mapper targets
> resolve backing devices by GUID instead of specifically by partition number.
> This could also be used in the init boot path (root=GUID) quite simply by
> modeling scanning code on printk_all_partitions(), or with another patchset
> allowing dm="" in the boot path: http://lkml.org/lkml/2010/6/7/418
>
> [ Additional context: http://codereview.chromium.org/3026039/show ]
>
> Would a change like this or something that exposes the GPT information via a
> walking function be something that would be of any interest, or is it explicitly
> against the current design/access goals with respect to partition information?
>
> Any and all feedback is truly appreciated.
>
> Signed-off-by: Will Drewry <wad@chromium.org>
> ---
> fs/partitions/efi.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/efi.h | 5 ++++
> 2 files changed, 66 insertions(+), 0 deletions(-)
>
> diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
> index 9efb2cf..4f642c5 100644
> --- a/fs/partitions/efi.c
> +++ b/fs/partitions/efi.c
> @@ -633,3 +633,64 @@ int efi_partition(struct parsed_partitions *state)
> printk("\n");
> return 1;
> }
> +
> +/**
> + * efi_partition_by_guid
> + * @bdev: Whole block device to scan for a GPT.
> + * @guid: Unique identifier for the partition to find.
> + *
> + * N.b., returns on the first match since it should be unique.
> + *
> + * Returns:
> + * -1 if an error occurred
> + * 0 if there was no match (or not GPT)
> + * >=1 is the index of the partition found.
> + *
> + */
> +int efi_partition_by_guid(struct block_device *bdev, efi_guid_t *guid) {
> + gpt_header *gpt = NULL;
> + gpt_entry *ptes = NULL;
> + u32 i;
> + struct parsed_partitions *state;
> + int part = 0;
> +
> + if (!bdev || !guid)
> + return -1;
> +
> + state = kzalloc(sizeof(struct parsed_partitions), GFP_KERNEL);
> + if (!state)
> + return -1;
> +
> + state->limit = disk_max_parts(bdev->bd_disk);
> + pr_debug(KERN_WARNING "efi_find_partition looking for gpt\n");
> +
> + state->bdev = bdev;
> + if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
> + pr_debug(KERN_WARNING "efi_find_partition no GPT\n");
> + kfree(gpt);
> + kfree(ptes);
> + kfree(state);
> + return 0;
> + }
> +
> + pr_debug("GUID Partition Table is valid! Yea!\n");
> + pr_debug(KERN_WARNING "efi_find_partition: 0 -> %d (limit:%d)\n",
> + le32_to_cpu(gpt->num_partition_entries),
> + state->limit);
> + for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) &&
> + i < state->limit-1; i++) {
> + if (!is_pte_valid(&ptes[i], last_lba(bdev)))
> + continue;
> +
> + /* Bails on first hit so duped "unique" GUIDs will be FCFS. */
> + if (!efi_guidcmp(ptes[i].unique_partition_guid,
> + *guid)) {
> + part = i + 1;
> + break;
> + }
> + }
> + kfree(ptes);
> + kfree(gpt);
> + kfree(state);
> + return part;
> +}
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index fb737bc..1a77259 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -301,6 +301,11 @@ extern unsigned long efi_get_time(void);
> extern int efi_set_rtc_mmss(unsigned long nowtime);
> extern struct efi_memory_map memmap;
>
> +#ifdef CONFIG_EFI_PARTITION
> +struct block_device;
> +extern int efi_partition_by_guid(struct block_device *bdev, efi_guid_t *guid);
> +#endif
> +
> /**
> * efi_range_is_wc - check the WC bit on an address range
> * @start: starting kvirt address

--
tejun


\
 
 \ /
  Last update: 2010-08-03 18:11    [W:0.103 / U:0.044 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site