From: NeilBrown Date: Wed, 12 Jan 2011 23:44:52 +0000 (+1100) Subject: reshape_array: move lots of code out of a 'switch'. X-Git-Tag: mdadm-3.2~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b2d630c7d9b5103a31f6353f31c4ea2564b86f6;p=thirdparty%2Fmdadm.git reshape_array: move lots of code out of a 'switch'. Everything other than the 'child' part of the 'switch(fork)' returns quickly, so leave them inside the switch but move the other large bit out so as to make the flow of code more natural. Signed-off-by: NeilBrown --- diff --git a/Grow.c b/Grow.c index 3dca265d..f8c010e9 100644 --- a/Grow.c +++ b/Grow.c @@ -1921,109 +1921,111 @@ static int reshape_array(char *container, int fd, char *devname, * This is all done by a forked background process. */ switch(forked ? 0 : fork()) { + case -1: + fprintf(stderr, Name ": Cannot run child to monitor reshape: %s\n", + strerror(errno)); + rv = 1; + abort_reshape(sra); + break; + default: + return 0; case 0: - close(fd); - if (check_env("MDADM_GROW_VERIFY")) - fd = open(devname, O_RDONLY | O_DIRECT); - else - fd = -1; - mlockall(MCL_FUTURE); + break; + } - odisks = reshape.before.data_disks + reshape.parity; + close(fd); + if (check_env("MDADM_GROW_VERIFY")) + fd = open(devname, O_RDONLY | O_DIRECT); + else + fd = -1; + mlockall(MCL_FUTURE); - if (st->ss->external) { - /* metadata handler takes it from here */ - done = st->ss->manage_reshape( - fd, sra, &reshape, st, blocks, - fdlist, offsets, - d - odisks, fdlist+odisks, - offsets+odisks); - } else - done = child_monitor( - fd, sra, &reshape, st, blocks, - fdlist, offsets, - d - odisks, fdlist+odisks, - offsets+odisks); - - if (backup_file && done) - unlink(backup_file); - if (!done) { - abort_reshape(sra); - goto out; - } - /* set new array size if required customer_array_size is used - * by this metadata. - */ - if (reshape.before.data_disks != - reshape.after.data_disks && - info->custom_array_size) { - struct mdinfo *info2; - char *subarray = strchr(info->text_version+1, '/')+1; + odisks = reshape.before.data_disks + reshape.parity; - wait_reshape(sra); - ping_monitor(container); + if (st->ss->external) { + /* metadata handler takes it from here */ + done = st->ss->manage_reshape( + fd, sra, &reshape, st, blocks, + fdlist, offsets, + d - odisks, fdlist+odisks, + offsets+odisks); + } else + done = child_monitor( + fd, sra, &reshape, st, blocks, + fdlist, offsets, + d - odisks, fdlist+odisks, + offsets+odisks); + + if (backup_file && done) + unlink(backup_file); + if (!done) { + abort_reshape(sra); + goto out; + } + /* set new array size if required customer_array_size is used + * by this metadata. + */ + if (reshape.before.data_disks != + reshape.after.data_disks && + info->custom_array_size) { + struct mdinfo *info2; + char *subarray = strchr(info->text_version+1, '/')+1; - info2 = st->ss->container_content(st, subarray); - if (info2) { - unsigned long long current_size = 0; - unsigned long long new_size = - info2->custom_array_size/2; - - if (sysfs_get_ll(sra, - NULL, - "array_size", - ¤t_size) == 0 && - new_size > current_size) { - if (sysfs_set_num(sra, NULL, - "array_size", new_size) - < 0) - dprintf("Error: Cannot" - " set array size"); - else - dprintf("Array size " - "changed"); - dprintf(" from %llu to %llu.\n", - current_size, new_size); - } - sysfs_free(info2); + wait_reshape(sra); + ping_monitor(container); + + info2 = st->ss->container_content(st, subarray); + if (info2) { + unsigned long long current_size = 0; + unsigned long long new_size = + info2->custom_array_size/2; + + if (sysfs_get_ll(sra, + NULL, + "array_size", + ¤t_size) == 0 && + new_size > current_size) { + if (sysfs_set_num(sra, NULL, + "array_size", new_size) + < 0) + dprintf("Error: Cannot" + " set array size"); + else + dprintf("Array size " + "changed"); + dprintf(" from %llu to %llu.\n", + current_size, new_size); } + sysfs_free(info2); } + } - if (info->new_level != reshape.level) { - /* We need to wait for the reshape to finish - * (which will have happened unless - * odata < ndata) and then set the level - */ + if (info->new_level != reshape.level) { + /* We need to wait for the reshape to finish + * (which will have happened unless + * odata < ndata) and then set the level + */ - if (reshape.before.data_disks < - reshape.after.data_disks) - wait_reshape(sra); + if (reshape.before.data_disks < + reshape.after.data_disks) + wait_reshape(sra); - c = map_num(pers, info->new_level); - if (c == NULL) - goto out;/* not possible */ + c = map_num(pers, info->new_level); + if (c == NULL) + goto out;/* not possible */ - err = sysfs_set_str(sra, NULL, "level", c); - if (err) - fprintf(stderr, Name\ - ": %s: could not set level " - "to %s\n", devname, c); - } - out: - if (forked) - return 0; - exit(0); - case -1: - fprintf(stderr, Name ": Cannot run child to monitor reshape: %s\n", - strerror(errno)); - rv = 1; - abort_reshape(sra); - break; - default: - return 0; + err = sysfs_set_str(sra, NULL, "level", c); + if (err) + fprintf(stderr, Name\ + ": %s: could not set level " + "to %s\n", devname, c); } +out: + if (forked) + return 0; + exit(0); - release: +release: if (!rv) { if (container) ping_monitor(container);