1 From 6a6a7657c231e947233c43ae0522bbd4edf0139e Mon Sep 17 00:00:00 2001 2 From: David Zeuthen <zeuthen (a] google.com> 3 Date: Tue, 24 Jan 2017 13:02:35 -0500 4 Subject: [PATCH 1/2] ANDROID: Update init/do_mounts_dm.c to the latest 5 ChromiumOS version. 6 7 This is needed for AVB integration work. 8 9 Bug: 31796270 10 Test: Manually tested (other arch). 11 Change-Id: I32fd37c1578c6414e3e6ff277d16ad94df7886b8 12 Signed-off-by: David Zeuthen <zeuthen (a] 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 18 diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h 19 index 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 */ 36 diff --git a/init/do_mounts_dm.c b/init/do_mounts_dm.c 37 index 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 -- 759 2.14.1.581.gf28d330327-goog 760 761