linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC] efi: add and expose efi_partition_by_guid
@ 2010-08-02 19:17 Will Drewry
  2010-08-02 23:00 ` David Miller
                   ` (2 more replies)
  0 siblings, 3 replies; 44+ messages in thread
From: Will Drewry @ 2010-08-02 19:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jens Axboe, Karel Zak, Tejun Heo, David S. Miller, Andrew Morton,
	Joe Perches, Will Drewry

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
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2010-09-15 14:22 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-02 19:17 [PATCH RFC] efi: add and expose efi_partition_by_guid Will Drewry
2010-08-02 23:00 ` David Miller
2010-08-03  2:44   ` Will Drewry
2010-08-03  2:52   ` [PATCH v2 " Will Drewry
2010-08-03 18:50     ` Randy Dunlap
2010-08-03 18:52       ` Will Drewry
2010-08-03  2:48 ` [PATCH RFC (alt)] efi: add efi_partition_walk and expose for kernel access Will Drewry
2010-08-03 16:08 ` [PATCH RFC] efi: add and expose efi_partition_by_guid Tejun Heo
2010-08-03 17:17   ` Kay Sievers
2010-08-03 17:55     ` Will Drewry
2010-08-03 18:23       ` Kay Sievers
2010-08-03 18:52         ` Will Drewry
2010-08-03 21:35           ` [PATCH 1/2] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-03 21:35           ` [PATCH 2/2] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-03 21:54             ` Kay Sievers
2010-08-03 22:27               ` Will Drewry
2010-08-03 23:13                 ` Kay Sievers
2010-08-04  2:04                   ` [PATCH v2 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-04  7:57                     ` Tejun Heo
2010-08-04 14:46                       ` Will Drewry
2010-08-04  2:04                   ` [PATCH v2 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04  7:59                     ` Tejun Heo
2010-08-04  9:00                     ` Karel Zak
2010-08-04 10:14                       ` Kay Sievers
2010-08-04 14:44                         ` Will Drewry
2010-08-04 15:28                           ` Kay Sievers
2010-08-04 15:56                             ` Will Drewry
2010-08-04 18:22                               ` [PATCH v3 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-08-04 18:22                               ` [PATCH v3 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04 18:22                               ` [PATCH v3 3/3] init: add support for root devices specified by partition UUID Will Drewry
2010-08-05 10:55                                 ` Tejun Heo
2010-08-05 14:26                                   ` Will Drewry
2010-08-05 14:29                                     ` Tejun Heo
2010-08-05 19:19                                       ` Will Drewry
2010-08-05 19:29                                 ` Kay Sievers
2010-08-31 20:47                                 ` [PATCH v4 1/3] block, partition: add partition_meta_info to hd_struct Will Drewry
2010-09-15 14:22                                   ` Jens Axboe
2010-08-31 20:47                                 ` [PATCH v4 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-31 20:47                                 ` [PATCH v4 3/3] init: add support for root devices specified by partition UUID Will Drewry
2010-08-04 14:44                       ` [PATCH v2 2/3] genhd, efi: add efi partition metadata to hd_structs Will Drewry
2010-08-04  2:04                   ` [PATCH 3/3] init: add support for root devices specified by partition UUID Will Drewry
2010-08-04 14:27                   ` [PATCH 2/2] genhd, efi: add efi partition metadata to hd_structs John Stoffel
2010-08-04 14:45                     ` Will Drewry
2010-08-04 15:25                       ` Kay Sievers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).