X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Create.c;h=330c5b428eaf83ca7244aa3bcbb66fe9e5bac66f;hb=6b781d331bf52b01b9bafa6409ffb400f8c62895;hp=63d50d67670a6fb5614b8ca227d02a62a444aa23;hpb=8baab049ce5df6342dd5556c8a0aa0e8ded7124b;p=thirdparty%2Fmdadm.git diff --git a/Create.c b/Create.c index 63d50d67..330c5b42 100644 --- a/Create.c +++ b/Create.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2012 Neil Brown + * Copyright (C) 2001-2013 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -285,6 +285,12 @@ int Create(struct supertype *st, char *mddev, info.array.active_disks = 0; info.array.working_disks = 0; dnum = 0; + for (dv = devlist; dv ; dv = dv->next) + if (data_offset == VARIABLE_OFFSET) + dv->data_offset = INVALID_SECTORS; + else + dv->data_offset = data_offset; + for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) { char *dname = dv->devname; unsigned long long freesize; @@ -509,6 +515,7 @@ int Create(struct supertype *st, char *mddev, if (!s->bitmap_file && s->level >= 1 && + st->ss->add_internal_bitmap && (s->write_behind || s->size > 100*1024*1024ULL)) { if (c->verbose > 0) pr_err("automatically enabling write-intent bitmap on large array\n"); @@ -687,6 +694,7 @@ int Create(struct supertype *st, char *mddev, /* base name on mddev */ /* /dev/md0 -> 0 * /dev/md_d0 -> d0 + * /dev/md_foo -> foo * /dev/md/1 -> 1 * /dev/md/d1 -> d1 * /dev/md/home -> home @@ -696,9 +704,8 @@ int Create(struct supertype *st, char *mddev, name = strrchr(mddev, '/'); if (name) { name++; - if (strncmp(name, "md_d", 4)==0 && - strlen(name) > 4 && - isdigit(name[4]) && + if (strncmp(name, "md_", 3)==0 && + strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */) name += 3; else if (strncmp(name, "md", 2)==0 && @@ -740,7 +747,9 @@ int Create(struct supertype *st, char *mddev, map_update(&map, fd2devnm(mdfd), info.text_version, info.uuid, chosen_name); - map_unlock(&map); + /* Keep map locked until devices have been added to array + * to stop another mdadm from finding and using those devices. + */ if (s->bitmap_file && vers < 9003) { major_num = BITMAP_MAJOR_HOSTENDIAN; @@ -753,18 +762,18 @@ int Create(struct supertype *st, char *mddev, if (s->bitmap_file && strcmp(s->bitmap_file, "internal")==0) { if ((vers%100) < 2) { pr_err("internal bitmaps not supported by this kernel.\n"); - goto abort; + goto abort_locked; } if (!st->ss->add_internal_bitmap) { pr_err("internal bitmaps not supported with %s metadata\n", st->ss->name); - goto abort; + goto abort_locked; } if (!st->ss->add_internal_bitmap(st, &s->bitmap_chunk, c->delay, s->write_behind, bitmapsize, 1, major_num)) { pr_err("Given bitmap chunk size not supported.\n"); - goto abort; + goto abort_locked; } s->bitmap_file = NULL; } @@ -790,7 +799,7 @@ int Create(struct supertype *st, char *mddev, if (container_fd < 0) { pr_err("Cannot get exclusive " "open on container - weird.\n"); - goto abort; + goto abort_locked; } if (mdmon_running(st->container_devnm)) { if (c->verbose) @@ -805,7 +814,7 @@ int Create(struct supertype *st, char *mddev, if (rv) { pr_err("failed to set array info for %s: %s\n", mddev, strerror(errno)); - goto abort; + goto abort_locked; } if (s->bitmap_file) { @@ -816,23 +825,23 @@ int Create(struct supertype *st, char *mddev, c->delay, s->write_behind, bitmapsize, major_num)) { - goto abort; + goto abort_locked; } bitmap_fd = open(s->bitmap_file, O_RDWR); if (bitmap_fd < 0) { pr_err("weird: %s cannot be openned\n", s->bitmap_file); - goto abort; + goto abort_locked; } if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { pr_err("Cannot set bitmap file for %s: %s\n", mddev, strerror(errno)); - goto abort; + goto abort_locked; } } infos = xmalloc(sizeof(*infos) * total_slots); - + enable_fds(total_slots); for (pass=1; pass <=2 ; pass++) { struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */ @@ -884,7 +893,7 @@ int Create(struct supertype *st, char *mddev, pr_err("failed to open %s " "after earlier success - aborting\n", dv->devname); - goto abort; + goto abort_locked; } fstat(fd, &stb); inf->disk.major = major(stb.st_rdev); @@ -896,7 +905,7 @@ int Create(struct supertype *st, char *mddev, fd, dv->devname, dv->data_offset)) { ioctl(mdfd, STOP_ARRAY, NULL); - goto abort; + goto abort_locked; } st->ss->getinfo_super(st, inf, NULL); safe_mode_delay = inf->safe_mode_delay; @@ -922,7 +931,7 @@ int Create(struct supertype *st, char *mddev, pr_err("ADD_NEW_DISK for %s " "failed: %s\n", dv->devname, strerror(errno)); - goto abort; + goto abort_locked; } break; } @@ -939,7 +948,6 @@ int Create(struct supertype *st, char *mddev, * the subarray cursor such that ->getinfo_super once * again returns container info. */ - map_lock(&map); st->ss->getinfo_super(st, &info_new, NULL); if (st->ss->external && s->level != LEVEL_CONTAINER && !same_uuid(info_new.uuid, info.uuid, 0)) { @@ -964,12 +972,12 @@ int Create(struct supertype *st, char *mddev, info_new.uuid, path); free(path); } - map_unlock(&map); flush_metadata_updates(st); st->ss->free_super(st); } } + map_unlock(&map); free(infos); if (s->level == LEVEL_CONTAINER) { @@ -1027,6 +1035,11 @@ int Create(struct supertype *st, char *mddev, ioctl(mdfd, STOP_ARRAY, NULL); goto abort; } + /* if start_ro module parameter is set, array is + * auto-read-only, which is bad as the resync won't + * start. So lets make it read-write now. + */ + ioctl(mdfd, RESTART_ARRAY_RW, NULL); } if (c->verbose >= 0) pr_err("array %s started.\n", mddev);