From 6b2d630c7d9b5103a31f6353f31c4ea2564b86f6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 13 Jan 2011 10:44:52 +1100 Subject: [PATCH] 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 --- Grow.c | 188 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 95 insertions(+), 93 deletions(-) diff --git a/Grow.c b/Grow.c index 3dca265..f8c010e 100644 --- a/Grow.c +++ b/Grow.c @@ -1921,98 +1921,6 @@ static int reshape_array(char *container, int fd, char *devname, * This is all done by a forked background process. */ switch(forked ? 0 : fork()) { - case 0: - close(fd); - if (check_env("MDADM_GROW_VERIFY")) - fd = open(devname, O_RDONLY | O_DIRECT); - else - fd = -1; - mlockall(MCL_FUTURE); - - odisks = reshape.before.data_disks + reshape.parity; - - 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; - - 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 (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 */ - - 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)); @@ -2021,9 +1929,103 @@ static int reshape_array(char *container, int fd, char *devname, break; default: return 0; + case 0: + break; } - release: + close(fd); + if (check_env("MDADM_GROW_VERIFY")) + fd = open(devname, O_RDONLY | O_DIRECT); + else + fd = -1; + mlockall(MCL_FUTURE); + + odisks = reshape.before.data_disks + reshape.parity; + + 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; + + 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 (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 */ + + 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: if (!rv) { if (container) ping_monitor(container);