diff options
author | Will Drewry <wad@chromium.org> | 2010-08-31 15:47:06 -0500 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-15 16:13:28 +0200 |
commit | eec7ecfede74bb996060efefd5c157acd5794e8a (patch) | |
tree | ecbe81ba3143aa8a90936a8acc51cc6a1cc6e01c /fs/partitions | |
parent | 6d1d8050b4bc89d0165d29b58e894aeba2564a97 (diff) | |
download | lwn-eec7ecfede74bb996060efefd5c157acd5794e8a.tar.gz lwn-eec7ecfede74bb996060efefd5c157acd5794e8a.zip |
genhd, efi: add efi partition metadata to hd_structs
This change extends the partition_meta_info structure to
support EFI GPT-specific metadata and ensures that data
is copied in on partition scanning.
Signed-off-by: Will Drewry <wad@chromium.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/efi.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c index dbb44d4bb8a7..ac0ccb5026a2 100644 --- a/fs/partitions/efi.c +++ b/fs/partitions/efi.c @@ -94,6 +94,7 @@ * ************************************************************/ #include <linux/crc32.h> +#include <linux/ctype.h> #include <linux/math64.h> #include <linux/slab.h> #include "check.h" @@ -604,6 +605,7 @@ int efi_partition(struct parsed_partitions *state) gpt_entry *ptes = NULL; u32 i; unsigned ssz = bdev_logical_block_size(state->bdev) / 512; + u8 unparsed_guid[37]; if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { kfree(gpt); @@ -614,6 +616,9 @@ int efi_partition(struct parsed_partitions *state) pr_debug("GUID Partition Table is valid! Yea!\n"); for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { + struct partition_meta_info *info; + unsigned label_count = 0; + unsigned label_max; u64 start = le64_to_cpu(ptes[i].starting_lba); u64 size = le64_to_cpu(ptes[i].ending_lba) - le64_to_cpu(ptes[i].starting_lba) + 1ULL; @@ -627,6 +632,26 @@ int efi_partition(struct parsed_partitions *state) if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID)) state->parts[i + 1].flags = ADDPART_FLAG_RAID; + + info = &state->parts[i + 1].info; + /* Instead of doing a manual swap to big endian, reuse the + * common ASCII hex format as the interim. + */ + efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid); + part_pack_uuid(unparsed_guid, info->uuid); + + /* Naively convert UTF16-LE to 7 bits. */ + label_max = min(sizeof(info->volname) - 1, + sizeof(ptes[i].partition_name)); + info->volname[label_max] = 0; + while (label_count < label_max) { + u8 c = ptes[i].partition_name[label_count] & 0xff; + if (c && !isprint(c)) + c = '!'; + info->volname[label_count] = c; + label_count++; + } + state->parts[i + 1].has_info = true; } kfree(ptes); kfree(gpt); |