aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-11-08 19:12:25 -0500
committerJens Axboe <axboe@kernel.dk>2012-11-23 08:28:53 -0500
commit1ad7e89940d5ac411928189e1a4a01901dbf590f (patch)
tree64bfe2bceb4d157320465d529869783443e031bf
parentd48c152a41c8cd6de832397b4ea6f0429ad86318 (diff)
block: store partition_meta_info.uuid as a string
This will allow other types of UUID to be stored here, aside from true UUIDs. This also simplifies code that uses this field, since it's usually constructed from a, used as a, or compared to other, strings. Note: A simplistic approach here would be to set uuid_str[36]=0 whenever a /PARTNROFF option was found to be present. However, this modifies the input string, and causes subsequent calls to devt_from_partuuid() not to see the /PARTNROFF option, which causes different results. In order to avoid misleading future maintainers, this parameter is marked const. Signed-off-by: Stephen Warren <swarren@nvidia.com> Cc: Tejun Heo <tj@kernel.org> Cc: Will Drewry <wad@chromium.org> Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/genhd.c8
-rw-r--r--block/partitions/efi.c7
-rw-r--r--include/linux/genhd.h8
-rw-r--r--init/do_mounts.c28
4 files changed, 25 insertions, 26 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 6cace663a80e..b281f3a2d26a 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -743,7 +743,6 @@ void __init printk_all_partitions(void)
743 struct hd_struct *part; 743 struct hd_struct *part;
744 char name_buf[BDEVNAME_SIZE]; 744 char name_buf[BDEVNAME_SIZE];
745 char devt_buf[BDEVT_SIZE]; 745 char devt_buf[BDEVT_SIZE];
746 char uuid_buf[PARTITION_META_INFO_UUIDLTH * 2 + 5];
747 746
748 /* 747 /*
749 * Don't show empty devices or things that have been 748 * Don't show empty devices or things that have been
@@ -762,16 +761,11 @@ void __init printk_all_partitions(void)
762 while ((part = disk_part_iter_next(&piter))) { 761 while ((part = disk_part_iter_next(&piter))) {
763 bool is_part0 = part == &disk->part0; 762 bool is_part0 = part == &disk->part0;
764 763
765 uuid_buf[0] = '\0';
766 if (part->info)
767 snprintf(uuid_buf, sizeof(uuid_buf), "%pU",
768 part->info->uuid);
769
770 printk("%s%s %10llu %s %s", is_part0 ? "" : " ", 764 printk("%s%s %10llu %s %s", is_part0 ? "" : " ",
771 bdevt_str(part_devt(part), devt_buf), 765 bdevt_str(part_devt(part), devt_buf),
772 (unsigned long long)part_nr_sects_read(part) >> 1 766 (unsigned long long)part_nr_sects_read(part) >> 1
773 , disk_name(disk, part->partno, name_buf), 767 , disk_name(disk, part->partno, name_buf),
774 uuid_buf); 768 part->info ? part->info->uuid : "");
775 if (is_part0) { 769 if (is_part0) {
776 if (disk->driverfs_dev != NULL && 770 if (disk->driverfs_dev != NULL &&
777 disk->driverfs_dev->driver != NULL) 771 disk->driverfs_dev->driver != NULL)
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 6296b403c67a..b62fb88b8711 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -620,7 +620,6 @@ int efi_partition(struct parsed_partitions *state)
620 gpt_entry *ptes = NULL; 620 gpt_entry *ptes = NULL;
621 u32 i; 621 u32 i;
622 unsigned ssz = bdev_logical_block_size(state->bdev) / 512; 622 unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
623 u8 unparsed_guid[37];
624 623
625 if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { 624 if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
626 kfree(gpt); 625 kfree(gpt);
@@ -649,11 +648,7 @@ int efi_partition(struct parsed_partitions *state)
649 state->parts[i + 1].flags = ADDPART_FLAG_RAID; 648 state->parts[i + 1].flags = ADDPART_FLAG_RAID;
650 649
651 info = &state->parts[i + 1].info; 650 info = &state->parts[i + 1].info;
652 /* Instead of doing a manual swap to big endian, reuse the 651 efi_guid_unparse(&ptes[i].unique_partition_guid, info->uuid);
653 * common ASCII hex format as the interim.
654 */
655 efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid);
656 part_pack_uuid(unparsed_guid, info->uuid);
657 652
658 /* Naively convert UTF16-LE to 7 bits. */ 653 /* Naively convert UTF16-LE to 7 bits. */
659 label_max = min(sizeof(info->volname) - 1, 654 label_max = min(sizeof(info->volname) - 1,
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 4f440b3e89fe..79b8bba19363 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -88,10 +88,14 @@ struct disk_stats {
88}; 88};
89 89
90#define PARTITION_META_INFO_VOLNAMELTH 64 90#define PARTITION_META_INFO_VOLNAMELTH 64
91#define PARTITION_META_INFO_UUIDLTH 16 91/*
92 * Enough for the string representation of any kind of UUID plus NULL.
93 * EFI UUID is 36 characters. MSDOS UUID is 11 characters.
94 */
95#define PARTITION_META_INFO_UUIDLTH 37
92 96
93struct partition_meta_info { 97struct partition_meta_info {
94 u8 uuid[PARTITION_META_INFO_UUIDLTH]; /* always big endian */ 98 char uuid[PARTITION_META_INFO_UUIDLTH];
95 u8 volname[PARTITION_META_INFO_VOLNAMELTH]; 99 u8 volname[PARTITION_META_INFO_VOLNAMELTH];
96}; 100};
97 101
diff --git a/init/do_mounts.c b/init/do_mounts.c
index f8a66424360d..b28ec5819325 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -69,23 +69,28 @@ __setup("ro", readonly);
69__setup("rw", readwrite); 69__setup("rw", readwrite);
70 70
71#ifdef CONFIG_BLOCK 71#ifdef CONFIG_BLOCK
72struct uuidcmp {
73 const char *uuid;
74 int len;
75};
76
72/** 77/**
73 * match_dev_by_uuid - callback for finding a partition using its uuid 78 * match_dev_by_uuid - callback for finding a partition using its uuid
74 * @dev: device passed in by the caller 79 * @dev: device passed in by the caller
75 * @data: opaque pointer to a 36 byte char array with a UUID 80 * @data: opaque pointer to the desired struct uuidcmp to match
76 * 81 *
77 * Returns 1 if the device matches, and 0 otherwise. 82 * Returns 1 if the device matches, and 0 otherwise.
78 */ 83 */
79static int match_dev_by_uuid(struct device *dev, void *data) 84static int match_dev_by_uuid(struct device *dev, void *data)
80{ 85{
81 u8 *uuid = data; 86 struct uuidcmp *cmp = data;
82 struct hd_struct *part = dev_to_part(dev); 87 struct hd_struct *part = dev_to_part(dev);
83 88
84 if (!part->info) 89 if (!part->info)
85 goto no_match; 90 goto no_match;
86 91
87 if (memcmp(uuid, part->info->uuid, sizeof(part->info->uuid))) 92 if (strncasecmp(cmp->uuid, part->info->uuid, cmp->len))
88 goto no_match; 93 goto no_match;
89 94
90 return 1; 95 return 1;
91no_match: 96no_match:
@@ -95,7 +100,7 @@ no_match:
95 100
96/** 101/**
97 * devt_from_partuuid - looks up the dev_t of a partition by its UUID 102 * devt_from_partuuid - looks up the dev_t of a partition by its UUID
98 * @uuid: min 36 byte char array containing a hex ascii UUID 103 * @uuid: char array containing ascii UUID
99 * 104 *
100 * The function will return the first partition which contains a matching 105 * The function will return the first partition which contains a matching
101 * UUID value in its partition_meta_info struct. This does not search 106 * UUID value in its partition_meta_info struct. This does not search
@@ -106,11 +111,11 @@ no_match:
106 * 111 *
107 * Returns the matching dev_t on success or 0 on failure. 112 * Returns the matching dev_t on success or 0 on failure.
108 */ 113 */
109static dev_t devt_from_partuuid(char *uuid_str) 114static dev_t devt_from_partuuid(const char *uuid_str)
110{ 115{
111 dev_t res = 0; 116 dev_t res = 0;
117 struct uuidcmp cmp;
112 struct device *dev = NULL; 118 struct device *dev = NULL;
113 u8 uuid[16];
114 struct gendisk *disk; 119 struct gendisk *disk;
115 struct hd_struct *part; 120 struct hd_struct *part;
116 int offset = 0; 121 int offset = 0;
@@ -118,6 +123,9 @@ static dev_t devt_from_partuuid(char *uuid_str)
118 if (strlen(uuid_str) < 36) 123 if (strlen(uuid_str) < 36)
119 goto done; 124 goto done;
120 125
126 cmp.uuid = uuid_str;
127 cmp.len = 36;
128
121 /* Check for optional partition number offset attributes. */ 129 /* Check for optional partition number offset attributes. */
122 if (uuid_str[36]) { 130 if (uuid_str[36]) {
123 char c = 0; 131 char c = 0;
@@ -134,10 +142,8 @@ static dev_t devt_from_partuuid(char *uuid_str)
134 } 142 }
135 } 143 }
136 144
137 /* Pack the requested UUID in the expected format. */ 145 dev = class_find_device(&block_class, NULL, &cmp,
138 part_pack_uuid(uuid_str, uuid); 146 &match_dev_by_uuid);
139
140 dev = class_find_device(&block_class, NULL, uuid, &match_dev_by_uuid);
141 if (!dev) 147 if (!dev)
142 goto done; 148 goto done;
143 149