diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c --- mdadm-4.2/Assemble.c 2025-10-25 11:46:59.647889913 +0800 +++ mdadm-4.2-fix/Assemble.c 2025-10-25 11:37:18.437758159 +0800 @@ -1337,10 +1337,8 @@ return 1; } -int Assemble(struct supertype *st, char *mddev, - struct mddev_ident *ident, - struct mddev_dev *devlist, - struct context *c) +int Assemble(char *mddev, struct mddev_ident *ident, + struct mddev_dev *devlist, struct context *c) { /* * The task of Assemble is to find a collection of @@ -1427,6 +1425,7 @@ char chosen_name[1024]; struct map_ent *map = NULL; struct map_ent *mp; + struct supertype *st = NULL; /* * If any subdevs are listed, then any that don't @@ -1447,6 +1446,15 @@ return 1; } + if (c->metadata) { + for (i = 0; !st && superlist[i]; i++) + st = superlist[i]->match_metadata_desc(c->metadata); + if (!st) { + pr_err("unrecognised metadata identifier: %s\n", c->metadata); + return -EINVAL; + } + } + if (devlist == NULL) devlist = conf_get_devs(); else if (mddev) @@ -1468,11 +1476,15 @@ st->ignore_hw_compat = 1; num_devs = select_devices(devlist, ident, &st, &content, c, inargv, auto_assem); - if (num_devs < 0) - return 1; + if (num_devs < 0) { + rv = 1; + goto free_st; + } - if (!st || !st->sb || !content) - return 2; + if (!st || !st->sb || !content) { + rv = 2; + goto free_st; + } /* We have a full set of devices - we now need to find the * array device. @@ -1603,11 +1615,10 @@ if (content != &info) { /* This is a member of a container. Try starting the array. */ - int err; - err = assemble_container_content(st, mdfd, content, c, + rv = assemble_container_content(st, mdfd, content, c, chosen_name, NULL); close(mdfd); - return err; + goto free_st; } /* Ok, no bad inconsistancy, we can try updating etc */ @@ -1961,9 +1972,19 @@ /* '2' means 'OK, but not started yet' */ if (rv == -1) { free(devices); - return 1; + rv = 1; + goto free_st; } - return rv == 2 ? 0 : rv; + + if (rv == 2) + rv = 0; +free_st: + if (st) { + st->ss->free_super(st); + free(st); + } + + return rv; } int assemble_container_content(struct supertype *st, int mdfd, diff -Naur mdadm-4.2/mdadm.c mdadm-4.2-fix/mdadm.c --- mdadm-4.2/mdadm.c 2025-10-25 11:46:59.527825090 +0800 +++ mdadm-4.2-fix/mdadm.c 2025-10-25 11:42:17.331226086 +0800 @@ -71,6 +71,7 @@ */ struct context c = { .require_homehost = 1, + .metadata = NULL, }; struct shape s = { .journaldisks = 0, @@ -402,6 +403,7 @@ pr_err("unrecognised metadata identifier: %s\n", optarg); exit(2); } + c.metadata = optarg; continue; case O(MANAGE,'W'): @@ -1427,10 +1429,10 @@ } else { if (array_ident->autof == 0) array_ident->autof = c.autof; - rv |= Assemble(ss, ident.devname, array_ident, NULL, &c); + rv |= Assemble(ident.devname, array_ident, NULL, &c); } } else if (!c.scan) - rv = Assemble(ss, ident.devname, &ident, devlist->next, &c); + rv = Assemble(ident.devname, &ident, devlist->next, &c); else if (devs_found > 0) { if (c.update && devs_found > 1) { pr_err("can only update a single array at a time\n"); @@ -1450,8 +1452,7 @@ } if (array_ident->autof == 0) array_ident->autof = c.autof; - rv |= Assemble(ss, dv->devname, array_ident, - NULL, &c); + rv |= Assemble(dv->devname, array_ident, NULL, &c); } } else { if (c.update) { @@ -1736,8 +1737,7 @@ if (a->devname && is_devname_ignore(a->devname) == true) continue; - r = Assemble(ss, a->devname, - a, NULL, c); + r = Assemble(a->devname, a, NULL, c); if (r == 0) { a->assembled = 1; successes++; @@ -1759,9 +1759,7 @@ struct mddev_dev *devlist = conf_get_devs(); acnt = 0; do { - rv2 = Assemble(ss, NULL, - ident, - devlist, c); + rv2 = Assemble(NULL, ident, devlist, c); if (rv2 == 0) { cnt++; acnt++; diff -Naur mdadm-4.2/mdadm.h mdadm-4.2-fix/mdadm.h --- mdadm-4.2/mdadm.h 2025-10-25 11:46:59.716186280 +0800 +++ mdadm-4.2-fix/mdadm.h 2025-10-25 11:43:13.999603357 +0800 @@ -662,6 +662,7 @@ char *action; int nodes; char *homecluster; + char *metadata; }; struct shape { @@ -1541,10 +1542,8 @@ extern int Grow_continue_command(char *devname, int fd, char *backup_file, int verbose); -extern int Assemble(struct supertype *st, char *mddev, - struct mddev_ident *ident, - struct mddev_dev *devlist, - struct context *c); +extern int Assemble(char *mddev, struct mddev_ident *ident, + struct mddev_dev *devlist, struct context *c); extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, struct context *c);