• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 6a6a7657c231e947233c43ae0522bbd4edf0139e Mon Sep 17 00:00:00 2001
2From: David Zeuthen <zeuthen@google.com>
3Date: Tue, 24 Jan 2017 13:02:35 -0500
4Subject: [PATCH 1/2] ANDROID: Update init/do_mounts_dm.c to the latest
5 ChromiumOS version.
6
7This is needed for AVB integration work.
8
9Bug: 31796270
10Test: Manually tested (other arch).
11Change-Id: I32fd37c1578c6414e3e6ff277d16ad94df7886b8
12Signed-off-by: David Zeuthen <zeuthen@google.com>
13---
14 include/linux/device-mapper.h |   7 +
15 init/do_mounts_dm.c           | 556 +++++++++++++++++++++++-------------------
16 2 files changed, 307 insertions(+), 256 deletions(-)
17
18diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
19index b874d5b61ffc..f3f87db34429 100644
20--- a/include/linux/device-mapper.h
21+++ b/include/linux/device-mapper.h
22@@ -415,6 +415,13 @@ union map_info *dm_get_rq_mapinfo(struct request *rq);
23
24 struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
25
26+void dm_lock_md_type(struct mapped_device *md);
27+void dm_unlock_md_type(struct mapped_device *md);
28+void dm_set_md_type(struct mapped_device *md, unsigned type);
29+unsigned dm_get_md_type(struct mapped_device *md);
30+int dm_setup_md_queue(struct mapped_device *md);
31+unsigned dm_table_get_type(struct dm_table *t);
32+
33 /*
34  * Geometry functions.
35  */
36diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c
37index ecda58df9a19..bce1c2fbb915 100644
38--- a/init/do_mounts_dm.c
39+++ b/init/do_mounts_dm.c
40@@ -5,13 +5,17 @@
41  *
42  * This file is released under the GPL.
43  */
44+#include <linux/async.h>
45+#include <linux/ctype.h>
46 #include <linux/device-mapper.h>
47 #include <linux/fs.h>
48 #include <linux/string.h>
49+#include <linux/delay.h>
50
51 #include "do_mounts.h"
52-#include "../drivers/md/dm.h"
53
54+#define DM_MAX_DEVICES 256
55+#define DM_MAX_TARGETS 256
56 #define DM_MAX_NAME 32
57 #define DM_MAX_UUID 129
58 #define DM_NO_UUID "none"
59@@ -19,14 +23,47 @@
60 #define DM_MSG_PREFIX "init"
61
62 /* Separators used for parsing the dm= argument. */
63-#define DM_FIELD_SEP ' '
64-#define DM_LINE_SEP ','
65+#define DM_FIELD_SEP " "
66+#define DM_LINE_SEP ","
67+#define DM_ANY_SEP DM_FIELD_SEP DM_LINE_SEP
68
69 /*
70  * When the device-mapper and any targets are compiled into the kernel
71- * (not a module), one target may be created and used as the root device at
72- * boot time with the parameters given with the boot line dm=...
73- * The code for that is here.
74+ * (not a module), one or more device-mappers may be created and used
75+ * as the root device at boot time with the parameters given with the
76+ * boot line dm=...
77+ *
78+ * Multiple device-mappers can be stacked specifing the number of
79+ * devices. A device can have multiple targets if the the number of
80+ * targets is specified.
81+ *
82+ * TODO(taysom:defect 32847)
83+ * In the future, the <num> field will be mandatory.
84+ *
85+ * <device>        ::= [<num>] <device-mapper>+
86+ * <device-mapper> ::= <head> "," <target>+
87+ * <head>          ::= <name> <uuid> <mode> [<num>]
88+ * <target>        ::= <start> <length> <type> <options> ","
89+ * <mode>          ::= "ro" | "rw"
90+ * <uuid>          ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | "none"
91+ * <type>          ::= "verity" | "bootcache" | ...
92+ *
93+ * Example:
94+ * 2 vboot none ro 1,
95+ *     0 1768000 bootcache
96+ *       device=aa55b119-2a47-8c45-946a-5ac57765011f+1
97+ *       signature=76e9be054b15884a9fa85973e9cb274c93afadb6
98+ *       cache_start=1768000 max_blocks=100000 size_limit=23 max_trace=20000,
99+ *   vroot none ro 1,
100+ *     0 1740800 verity payload=254:0 hashtree=254:0 hashstart=1740800 alg=sha1
101+ *       root_hexdigest=76e9be054b15884a9fa85973e9cb274c93afadb6
102+ *       salt=5b3549d54d6c7a3837b9b81ed72e49463a64c03680c47835bef94d768e5646fe
103+ *
104+ * Notes:
105+ *  1. uuid is a label for the device and we set it to "none".
106+ *  2. The <num> field will be optional initially and assumed to be 1.
107+ *     Once all the scripts that set these fields have been set, it will
108+ *     be made mandatory.
109  */
110
111 struct dm_setup_target {
112@@ -38,381 +75,388 @@ struct dm_setup_target {
113 	struct dm_setup_target *next;
114 };
115
116-static struct {
117+struct dm_device {
118 	int minor;
119 	int ro;
120 	char name[DM_MAX_NAME];
121 	char uuid[DM_MAX_UUID];
122-	char *targets;
123+	unsigned long num_targets;
124 	struct dm_setup_target *target;
125 	int target_count;
126+	struct dm_device *next;
127+};
128+
129+struct dm_option {
130+	char *start;
131+	char *next;
132+	size_t len;
133+	char delim;
134+};
135+
136+static struct {
137+	unsigned long num_devices;
138+	char *str;
139 } dm_setup_args __initdata;
140
141 static __initdata int dm_early_setup;
142
143-static size_t __init get_dm_option(char *str, char **next, char sep)
144+static int __init get_dm_option(struct dm_option *opt, const char *accept)
145 {
146-	size_t len = 0;
147-	char *endp = NULL;
148+	char *str = opt->next;
149+	char *endp;
150
151 	if (!str)
152 		return 0;
153
154-	endp = strchr(str, sep);
155+	str = skip_spaces(str);
156+	opt->start = str;
157+	endp = strpbrk(str, accept);
158 	if (!endp) {  /* act like strchrnul */
159-		len = strlen(str);
160-		endp = str + len;
161+		opt->len = strlen(str);
162+		endp = str + opt->len;
163 	} else {
164-		len = endp - str;
165+		opt->len = endp - str;
166 	}
167-
168-	if (endp == str)
169-		return 0;
170-
171-	if (!next)
172-		return len;
173-
174+	opt->delim = *endp;
175 	if (*endp == 0) {
176 		/* Don't advance past the nul. */
177-		*next = endp;
178+		opt->next = endp;
179 	} else {
180-		*next = endp + 1;
181+		opt->next = endp + 1;
182 	}
183-	return len;
184-}
185-
186-static int __init dm_setup_args_init(void)
187-{
188-	dm_setup_args.minor = 0;
189-	dm_setup_args.ro = 0;
190-	dm_setup_args.target = NULL;
191-	dm_setup_args.target_count = 0;
192-	return 0;
193+	return opt->len != 0;
194 }
195
196-static int __init dm_setup_cleanup(void)
197+static int __init dm_setup_cleanup(struct dm_device *devices)
198 {
199-	struct dm_setup_target *target = dm_setup_args.target;
200-	struct dm_setup_target *old_target = NULL;
201-	while (target) {
202-		kfree(target->type);
203-		kfree(target->params);
204-		old_target = target;
205-		target = target->next;
206-		kfree(old_target);
207-		dm_setup_args.target_count--;
208+	struct dm_device *dev = devices;
209+
210+	while (dev) {
211+		struct dm_device *old_dev = dev;
212+		struct dm_setup_target *target = dev->target;
213+		while (target) {
214+			struct dm_setup_target *old_target = target;
215+			kfree(target->type);
216+			kfree(target->params);
217+			target = target->next;
218+			kfree(old_target);
219+			dev->target_count--;
220+		}
221+		BUG_ON(dev->target_count);
222+		dev = dev->next;
223+		kfree(old_dev);
224 	}
225-	BUG_ON(dm_setup_args.target_count);
226 	return 0;
227 }
228
229-static char * __init dm_setup_parse_device_args(char *str)
230+static char * __init dm_parse_device(struct dm_device *dev, char *str)
231 {
232-	char *next = NULL;
233-	size_t len = 0;
234+	struct dm_option opt;
235+	size_t len;
236
237 	/* Grab the logical name of the device to be exported to udev */
238-	len = get_dm_option(str, &next, DM_FIELD_SEP);
239-	if (!len) {
240+	opt.next = str;
241+	if (!get_dm_option(&opt, DM_FIELD_SEP)) {
242 		DMERR("failed to parse device name");
243 		goto parse_fail;
244 	}
245-	len = min(len + 1, sizeof(dm_setup_args.name));
246-	strlcpy(dm_setup_args.name, str, len);  /* includes nul */
247-	str = skip_spaces(next);
248+	len = min(opt.len + 1, sizeof(dev->name));
249+	strlcpy(dev->name, opt.start, len);  /* includes nul */
250
251 	/* Grab the UUID value or "none" */
252-	len = get_dm_option(str, &next, DM_FIELD_SEP);
253-	if (!len) {
254+	if (!get_dm_option(&opt, DM_FIELD_SEP)) {
255 		DMERR("failed to parse device uuid");
256 		goto parse_fail;
257 	}
258-	len = min(len + 1, sizeof(dm_setup_args.uuid));
259-	strlcpy(dm_setup_args.uuid, str, len);
260-	str = skip_spaces(next);
261+	len = min(opt.len + 1, sizeof(dev->uuid));
262+	strlcpy(dev->uuid, opt.start, len);
263
264 	/* Determine if the table/device will be read only or read-write */
265-	if (!strncmp("ro,", str, 3)) {
266-		dm_setup_args.ro = 1;
267-	} else if (!strncmp("rw,", str, 3)) {
268-		dm_setup_args.ro = 0;
269+	get_dm_option(&opt, DM_ANY_SEP);
270+	if (!strncmp("ro", opt.start, opt.len)) {
271+		dev->ro = 1;
272+	} else if (!strncmp("rw", opt.start, opt.len)) {
273+		dev->ro = 0;
274 	} else {
275 		DMERR("failed to parse table mode");
276 		goto parse_fail;
277 	}
278-	str = skip_spaces(str + 3);
279
280-	return str;
281+	/* Optional number field */
282+	/* XXX: The <num> field will be mandatory in the next round */
283+	if (opt.delim == DM_FIELD_SEP[0]) {
284+		if (!get_dm_option(&opt, DM_LINE_SEP))
285+			return NULL;
286+		dev->num_targets = simple_strtoul(opt.start, NULL, 10);
287+	} else {
288+		dev->num_targets = 1;
289+	}
290+	if (dev->num_targets > DM_MAX_TARGETS) {
291+		DMERR("too many targets %lu > %d",
292+			dev->num_targets, DM_MAX_TARGETS);
293+	}
294+	return opt.next;
295
296 parse_fail:
297 	return NULL;
298 }
299
300-static void __init dm_substitute_devices(char *str, size_t str_len)
301+static char * __init dm_parse_targets(struct dm_device *dev, char *str)
302 {
303-	char *candidate = str;
304-	char *candidate_end = str;
305-	char old_char;
306-	size_t len = 0;
307-	dev_t dev;
308-
309-	if (str_len < 3)
310-		return;
311-
312-	while (str && *str) {
313-		candidate = strchr(str, '/');
314-		if (!candidate)
315-			break;
316-
317-		/* Avoid embedded slashes */
318-		if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) {
319-			str = strchr(candidate, DM_FIELD_SEP);
320-			continue;
321-		}
322-
323-		len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP);
324-		str = skip_spaces(candidate_end);
325-		if (len < 3 || len > 37)  /* name_to_dev_t max; maj:mix min */
326-			continue;
327-
328-		/* Temporarily terminate with a nul */
329-		if (*candidate_end)
330-			candidate_end--;
331-		old_char = *candidate_end;
332-		*candidate_end = '\0';
333-
334-		DMDEBUG("converting candidate device '%s' to dev_t", candidate);
335-		/* Use the boot-time specific device naming */
336-		dev = name_to_dev_t(candidate);
337-		*candidate_end = old_char;
338-
339-		DMDEBUG(" -> %u", dev);
340-		/* No suitable replacement found */
341-		if (!dev)
342-			continue;
343-
344-		/* Rewrite the /dev/path as a major:minor */
345-		len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev));
346-		if (!len) {
347-			DMERR("error substituting device major/minor.");
348-			break;
349-		}
350-		candidate += len;
351-		/* Pad out with spaces (fixing our nul) */
352-		while (candidate < candidate_end)
353-			*(candidate++) = DM_FIELD_SEP;
354-	}
355-}
356-
357-static int __init dm_setup_parse_targets(char *str)
358-{
359-	char *next = NULL;
360-	size_t len = 0;
361-	struct dm_setup_target **target = NULL;
362+	struct dm_option opt;
363+	struct dm_setup_target **target = &dev->target;
364+	unsigned long num_targets = dev->num_targets;
365+	unsigned long i;
366
367 	/* Targets are defined as per the table format but with a
368 	 * comma as a newline separator. */
369-	target = &dm_setup_args.target;
370-	while (str && *str) {
371+	opt.next = str;
372+	for (i = 0; i < num_targets; i++) {
373 		*target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL);
374 		if (!*target) {
375-			DMERR("failed to allocate memory for target %d",
376-			      dm_setup_args.target_count);
377+			DMERR("failed to allocate memory for target %s<%ld>",
378+				dev->name, i);
379 			goto parse_fail;
380 		}
381-		dm_setup_args.target_count++;
382+		dev->target_count++;
383
384-		(*target)->begin = simple_strtoull(str, &next, 10);
385-		if (!next || *next != DM_FIELD_SEP) {
386-			DMERR("failed to parse starting sector for target %d",
387-			      dm_setup_args.target_count - 1);
388+		if (!get_dm_option(&opt, DM_FIELD_SEP)) {
389+			DMERR("failed to parse starting sector"
390+				" for target %s<%ld>", dev->name, i);
391 			goto parse_fail;
392 		}
393-		str = skip_spaces(next + 1);
394+		(*target)->begin = simple_strtoull(opt.start, NULL, 10);
395
396-		(*target)->length = simple_strtoull(str, &next, 10);
397-		if (!next || *next != DM_FIELD_SEP) {
398-			DMERR("failed to parse length for target %d",
399-			      dm_setup_args.target_count - 1);
400+		if (!get_dm_option(&opt, DM_FIELD_SEP)) {
401+			DMERR("failed to parse length for target %s<%ld>",
402+				dev->name, i);
403 			goto parse_fail;
404 		}
405-		str = skip_spaces(next + 1);
406-
407-		len = get_dm_option(str, &next, DM_FIELD_SEP);
408-		if (!len ||
409-		    !((*target)->type = kstrndup(str, len, GFP_KERNEL))) {
410-			DMERR("failed to parse type for target %d",
411-			      dm_setup_args.target_count - 1);
412+		(*target)->length = simple_strtoull(opt.start, NULL, 10);
413+
414+		if (get_dm_option(&opt, DM_FIELD_SEP))
415+			(*target)->type = kstrndup(opt.start, opt.len,
416+							GFP_KERNEL);
417+		if (!((*target)->type)) {
418+			DMERR("failed to parse type for target %s<%ld>",
419+				dev->name, i);
420 			goto parse_fail;
421 		}
422-		str = skip_spaces(next);
423-
424-		len = get_dm_option(str, &next, DM_LINE_SEP);
425-		if (!len ||
426-		    !((*target)->params = kstrndup(str, len, GFP_KERNEL))) {
427-			DMERR("failed to parse params for target %d",
428-			      dm_setup_args.target_count - 1);
429+		if (get_dm_option(&opt, DM_LINE_SEP))
430+			(*target)->params = kstrndup(opt.start, opt.len,
431+							GFP_KERNEL);
432+		if (!((*target)->params)) {
433+			DMERR("failed to parse params for target %s<%ld>",
434+				dev->name, i);
435 			goto parse_fail;
436 		}
437-		str = skip_spaces(next);
438-
439-		/* Before moving on, walk through the copied target and
440-		 * attempt to replace all /dev/xxx with the major:minor number.
441-		 * It may not be possible to resolve them traditionally at
442-		 * boot-time. */
443-		dm_substitute_devices((*target)->params, len);
444-
445 		target = &((*target)->next);
446 	}
447-	DMDEBUG("parsed %d targets", dm_setup_args.target_count);
448+	DMDEBUG("parsed %d targets", dev->target_count);
449
450-	return 0;
451+	return opt.next;
452
453 parse_fail:
454-	return 1;
455+	return NULL;
456+}
457+
458+static struct dm_device * __init dm_parse_args(void)
459+{
460+	struct dm_device *devices = NULL;
461+	struct dm_device **tail = &devices;
462+	struct dm_device *dev;
463+	char *str = dm_setup_args.str;
464+	unsigned long num_devices = dm_setup_args.num_devices;
465+	unsigned long i;
466+
467+	if (!str)
468+		return NULL;
469+	for (i = 0; i < num_devices; i++) {
470+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
471+		if (!dev) {
472+			DMERR("failed to allocated memory for dev");
473+			goto error;
474+		}
475+		*tail = dev;
476+		tail = &dev->next;
477+		/*
478+		 * devices are given minor numbers 0 - n-1
479+		 * in the order they are found in the arg
480+		 * string.
481+		 */
482+		dev->minor = i;
483+		str = dm_parse_device(dev, str);
484+		if (!str)	/* NULL indicates error in parsing, bail */
485+			goto error;
486+
487+		str = dm_parse_targets(dev, str);
488+		if (!str)
489+			goto error;
490+	}
491+	return devices;
492+error:
493+	dm_setup_cleanup(devices);
494+	return NULL;
495 }
496
497 /*
498  * Parse the command-line parameters given our kernel, but do not
499  * actually try to invoke the DM device now; that is handled by
500- * dm_setup_drive after the low-level disk drivers have initialised.
501- * dm format is as follows:
502- *  dm="name uuid fmode,[table line 1],[table line 2],..."
503- * May be used with root=/dev/dm-0 as it always uses the first dm minor.
504+ * dm_setup_drives after the low-level disk drivers have initialised.
505+ * dm format is described at the top of the file.
506+ *
507+ * Because dm minor numbers are assigned in assending order starting with 0,
508+ * You can assume the first device is /dev/dm-0, the next device is /dev/dm-1,
509+ * and so forth.
510  */
511-
512 static int __init dm_setup(char *str)
513 {
514-	dm_setup_args_init();
515+	struct dm_option opt;
516+	unsigned long num_devices;
517
518-	str = dm_setup_parse_device_args(str);
519 	if (!str) {
520 		DMDEBUG("str is NULL");
521 		goto parse_fail;
522 	}
523-
524-	/* Target parsing is delayed until we have dynamic memory */
525-	dm_setup_args.targets = str;
526-
527-	printk(KERN_INFO "dm: will configure '%s' on dm-%d\n",
528-	       dm_setup_args.name, dm_setup_args.minor);
529-
530+	opt.next = str;
531+	if (!get_dm_option(&opt, DM_FIELD_SEP))
532+		goto parse_fail;
533+	if (isdigit(opt.start[0])) {	/* XXX: Optional number field */
534+		num_devices = simple_strtoul(opt.start, NULL, 10);
535+		str = opt.next;
536+	} else {
537+		num_devices = 1;
538+		/* Don't advance str */
539+	}
540+	if (num_devices > DM_MAX_DEVICES) {
541+		DMDEBUG("too many devices %lu > %d",
542+			num_devices, DM_MAX_DEVICES);
543+	}
544+	dm_setup_args.str = str;
545+	dm_setup_args.num_devices = num_devices;
546+	DMINFO("will configure %lu devices", num_devices);
547 	dm_early_setup = 1;
548 	return 1;
549
550 parse_fail:
551-	printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n");
552+	DMWARN("Invalid arguments supplied to dm=.");
553 	return 0;
554 }
555
556-
557-static void __init dm_setup_drive(void)
558+static void __init dm_setup_drives(void)
559 {
560 	struct mapped_device *md = NULL;
561 	struct dm_table *table = NULL;
562 	struct dm_setup_target *target;
563-	char *uuid = dm_setup_args.uuid;
564+	struct dm_device *dev;
565+	char *uuid;
566 	fmode_t fmode = FMODE_READ;
567+	struct dm_device *devices;
568
569-	/* Finish parsing the targets. */
570-	if (dm_setup_parse_targets(dm_setup_args.targets))
571-		goto parse_fail;
572-
573-	if (dm_create(dm_setup_args.minor, &md)) {
574-		DMDEBUG("failed to create the device");
575-		goto dm_create_fail;
576-	}
577-	DMDEBUG("created device '%s'", dm_device_name(md));
578-
579-	/* In addition to flagging the table below, the disk must be
580-	 * set explicitly ro/rw. */
581-	set_disk_ro(dm_disk(md), dm_setup_args.ro);
582+	devices = dm_parse_args();
583
584-	if (!dm_setup_args.ro)
585-		fmode |= FMODE_WRITE;
586-	if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) {
587-		DMDEBUG("failed to create the table");
588-		goto dm_table_create_fail;
589-	}
590+	for (dev = devices; dev; dev = dev->next) {
591+		if (dm_create(dev->minor, &md)) {
592+			DMDEBUG("failed to create the device");
593+			goto dm_create_fail;
594+		}
595+		DMDEBUG("created device '%s'", dm_device_name(md));
596+
597+		/*
598+		 * In addition to flagging the table below, the disk must be
599+		 * set explicitly ro/rw.
600+		 */
601+		set_disk_ro(dm_disk(md), dev->ro);
602+
603+		if (!dev->ro)
604+			fmode |= FMODE_WRITE;
605+		if (dm_table_create(&table, fmode, dev->target_count, md)) {
606+			DMDEBUG("failed to create the table");
607+			goto dm_table_create_fail;
608+		}
609
610-	dm_lock_md_type(md);
611-	target = dm_setup_args.target;
612-	while (target) {
613-		DMINFO("adding target '%llu %llu %s %s'",
614-		       (unsigned long long) target->begin,
615-		       (unsigned long long) target->length, target->type,
616-		       target->params);
617-		if (dm_table_add_target(table, target->type, target->begin,
618-					target->length, target->params)) {
619-			DMDEBUG("failed to add the target to the table");
620-			goto add_target_fail;
621+		dm_lock_md_type(md);
622+
623+		for (target = dev->target; target; target = target->next) {
624+			DMINFO("adding target '%llu %llu %s %s'",
625+			       (unsigned long long) target->begin,
626+			       (unsigned long long) target->length,
627+			       target->type, target->params);
628+			if (dm_table_add_target(table, target->type,
629+						target->begin,
630+						target->length,
631+						target->params)) {
632+				DMDEBUG("failed to add the target"
633+					" to the table");
634+				goto add_target_fail;
635+			}
636+		}
637+		if (dm_table_complete(table)) {
638+			DMDEBUG("failed to complete the table");
639+			goto table_complete_fail;
640 		}
641-		target = target->next;
642-	}
643
644-	if (dm_table_complete(table)) {
645-		DMDEBUG("failed to complete the table");
646-		goto table_complete_fail;
647-	}
648+		/* Suspend the device so that we can bind it to the table. */
649+		if (dm_suspend(md, 0)) {
650+			DMDEBUG("failed to suspend the device pre-bind");
651+			goto suspend_fail;
652+		}
653
654-	if (dm_get_md_type(md) == DM_TYPE_NONE) {
655+		/* Initial table load: acquire type of table. */
656 		dm_set_md_type(md, dm_table_get_type(table));
657+
658+		/* Setup md->queue to reflect md's type. */
659 		if (dm_setup_md_queue(md)) {
660 			DMWARN("unable to set up device queue for new table.");
661 			goto setup_md_queue_fail;
662 		}
663-	} else if (dm_get_md_type(md) != dm_table_get_type(table)) {
664-		DMWARN("can't change device type after initial table load.");
665-		goto setup_md_queue_fail;
666-        }
667-
668-	/* Suspend the device so that we can bind it to the table. */
669-	if (dm_suspend(md, 0)) {
670-		DMDEBUG("failed to suspend the device pre-bind");
671-		goto suspend_fail;
672-	}
673
674-	/* Bind the table to the device. This is the only way to associate
675-	 * md->map with the table and set the disk capacity directly. */
676-	if (dm_swap_table(md, table)) {  /* should return NULL. */
677-		DMDEBUG("failed to bind the device to the table");
678-		goto table_bind_fail;
679-	}
680+		/*
681+		 * Bind the table to the device. This is the only way
682+		 * to associate md->map with the table and set the disk
683+		 * capacity directly.
684+		 */
685+		if (dm_swap_table(md, table)) {  /* should return NULL. */
686+			DMDEBUG("failed to bind the device to the table");
687+			goto table_bind_fail;
688+		}
689
690-	/* Finally, resume and the device should be ready. */
691-	if (dm_resume(md)) {
692-		DMDEBUG("failed to resume the device");
693-		goto resume_fail;
694-	}
695+		/* Finally, resume and the device should be ready. */
696+		if (dm_resume(md)) {
697+			DMDEBUG("failed to resume the device");
698+			goto resume_fail;
699+		}
700
701-	/* Export the dm device via the ioctl interface */
702-	if (!strcmp(DM_NO_UUID, dm_setup_args.uuid))
703-		uuid = NULL;
704-	if (dm_ioctl_export(md, dm_setup_args.name, uuid)) {
705-		DMDEBUG("failed to export device with given name and uuid");
706-		goto export_fail;
707-	}
708-	printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor);
709+		/* Export the dm device via the ioctl interface */
710+		if (!strcmp(DM_NO_UUID, dev->uuid))
711+			uuid = NULL;
712+		if (dm_ioctl_export(md, dev->name, uuid)) {
713+			DMDEBUG("failed to export device with given"
714+				" name and uuid");
715+			goto export_fail;
716+		}
717
718-	dm_unlock_md_type(md);
719-	dm_setup_cleanup();
720+		dm_unlock_md_type(md);
721+
722+		DMINFO("dm-%d is ready", dev->minor);
723+	}
724+	dm_setup_cleanup(devices);
725 	return;
726
727 export_fail:
728 resume_fail:
729 table_bind_fail:
730-suspend_fail:
731 setup_md_queue_fail:
732+suspend_fail:
733 table_complete_fail:
734 add_target_fail:
735 	dm_unlock_md_type(md);
736 dm_table_create_fail:
737 	dm_put(md);
738 dm_create_fail:
739-	dm_setup_cleanup();
740-parse_fail:
741-	printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n",
742-	       dm_setup_args.minor, dm_setup_args.name);
743+	DMWARN("starting dm-%d (%s) failed",
744+	       dev->minor, dev->name);
745+	dm_setup_cleanup(devices);
746 }
747
748 __setup("dm=", dm_setup);
749@@ -421,6 +465,6 @@ void __init dm_run_setup(void)
750 {
751 	if (!dm_early_setup)
752 		return;
753-	printk(KERN_INFO "dm: attempting early device configuration.\n");
754-	dm_setup_drive();
755+	DMINFO("attempting early device configuration.");
756+	dm_setup_drives();
757 }
758--
7592.14.1.581.gf28d330327-goog
760
761