aboutsummaryrefslogtreecommitdiffstats
path: root/init/do_mounts.c
diff options
context:
space:
mode:
Diffstat (limited to 'init/do_mounts.c')
-rw-r--r--init/do_mounts.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c
index c0851a8e030c..0f6e1d985a3b 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -28,7 +28,7 @@ int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
28int root_mountflags = MS_RDONLY | MS_SILENT; 28int root_mountflags = MS_RDONLY | MS_SILENT;
29static char * __initdata root_device_name; 29static char * __initdata root_device_name;
30static char __initdata saved_root_name[64]; 30static char __initdata saved_root_name[64];
31static int __initdata root_wait; 31static int root_wait;
32 32
33dev_t ROOT_DEV; 33dev_t ROOT_DEV;
34 34
@@ -85,12 +85,15 @@ no_match:
85 85
86/** 86/**
87 * devt_from_partuuid - looks up the dev_t of a partition by its UUID 87 * devt_from_partuuid - looks up the dev_t of a partition by its UUID
88 * @uuid: 36 byte char array containing a hex ascii UUID 88 * @uuid: min 36 byte char array containing a hex ascii UUID
89 * 89 *
90 * The function will return the first partition which contains a matching 90 * The function will return the first partition which contains a matching
91 * UUID value in its partition_meta_info struct. This does not search 91 * UUID value in its partition_meta_info struct. This does not search
92 * by filesystem UUIDs. 92 * by filesystem UUIDs.
93 * 93 *
94 * If @uuid is followed by a "/PARTNROFF=%d", then the number will be
95 * extracted and used as an offset from the partition identified by the UUID.
96 *
94 * Returns the matching dev_t on success or 0 on failure. 97 * Returns the matching dev_t on success or 0 on failure.
95 */ 98 */
96static dev_t devt_from_partuuid(char *uuid_str) 99static dev_t devt_from_partuuid(char *uuid_str)
@@ -98,6 +101,28 @@ static dev_t devt_from_partuuid(char *uuid_str)
98 dev_t res = 0; 101 dev_t res = 0;
99 struct device *dev = NULL; 102 struct device *dev = NULL;
100 u8 uuid[16]; 103 u8 uuid[16];
104 struct gendisk *disk;
105 struct hd_struct *part;
106 int offset = 0;
107
108 if (strlen(uuid_str) < 36)
109 goto done;
110
111 /* Check for optional partition number offset attributes. */
112 if (uuid_str[36]) {
113 char c = 0;
114 /* Explicitly fail on poor PARTUUID syntax. */
115 if (sscanf(&uuid_str[36],
116 "/PARTNROFF=%d%c", &offset, &c) != 1) {
117 printk(KERN_ERR "VFS: PARTUUID= is invalid.\n"
118 "Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d]\n");
119 if (root_wait)
120 printk(KERN_ERR
121 "Disabling rootwait; root= is invalid.\n");
122 root_wait = 0;
123 goto done;
124 }
125 }
101 126
102 /* Pack the requested UUID in the expected format. */ 127 /* Pack the requested UUID in the expected format. */
103 part_pack_uuid(uuid_str, uuid); 128 part_pack_uuid(uuid_str, uuid);
@@ -107,8 +132,21 @@ static dev_t devt_from_partuuid(char *uuid_str)
107 goto done; 132 goto done;
108 133
109 res = dev->devt; 134 res = dev->devt;
110 put_device(dev);
111 135
136 /* Attempt to find the partition by offset. */
137 if (!offset)
138 goto no_offset;
139
140 res = 0;
141 disk = part_to_disk(dev_to_part(dev));
142 part = disk_get_part(disk, dev_to_part(dev)->partno + offset);
143 if (part) {
144 res = part_devt(part);
145 put_device(part_to_dev(part));
146 }
147
148no_offset:
149 put_device(dev);
112done: 150done:
113 return res; 151 return res;
114} 152}
@@ -126,6 +164,8 @@ done:
126 * used when disk name of partitioned disk ends on a digit. 164 * used when disk name of partitioned disk ends on a digit.
127 * 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the 165 * 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the
128 * unique id of a partition if the partition table provides it. 166 * unique id of a partition if the partition table provides it.
167 * 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to
168 * a partition with a known unique id.
129 * 169 *
130 * If name doesn't have fall into the categories above, we return (0,0). 170 * If name doesn't have fall into the categories above, we return (0,0).
131 * block_class is used to check if something is a disk name. If the disk 171 * block_class is used to check if something is a disk name. If the disk
@@ -143,8 +183,6 @@ dev_t name_to_dev_t(char *name)
143#ifdef CONFIG_BLOCK 183#ifdef CONFIG_BLOCK
144 if (strncmp(name, "PARTUUID=", 9) == 0) { 184 if (strncmp(name, "PARTUUID=", 9) == 0) {
145 name += 9; 185 name += 9;
146 if (strlen(name) != 36)
147 goto fail;
148 res = devt_from_partuuid(name); 186 res = devt_from_partuuid(name);
149 if (!res) 187 if (!res)
150 goto fail; 188 goto fail;