diff options
author | NeilBrown <neilb@suse.de> | 2013-06-27 10:12:31 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-06-27 10:12:31 +1000 |
commit | a73b00811cf8b0c36bcf66c356951857fb37ce77 (patch) | |
tree | 9e4fdac6d39bbe2393e69c38887e1a6896a20acb /Grow.c | |
parent | b379508eeb26273f6044080788ffa1eb257c96f4 (diff) |
Grow: report better message when --grow --chunk cannot work.
When changing the chunksize of an array, the new chunksize must
divide the device size.
If it doesn't we report a very brief message.
Make this message a bit longer and suggest a way forward be reducing
the size of the array.
Reported-by: Mark Knecht <markknecht@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 23 |
1 files changed, 16 insertions, 7 deletions
@@ -963,7 +963,7 @@ unsigned long compute_backup_blocks(int nchunk, int ochunk, return blocks; } -char *analyse_change(struct mdinfo *info, struct reshape *re) +char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) { /* Based on the current array state in info->array and * the changes in info->new_* etc, determine: @@ -1004,9 +1004,16 @@ char *analyse_change(struct mdinfo *info, struct reshape *re) /* chunk size is meaningful, must divide component_size * evenly */ - if (info->component_size % (info->new_chunk/512)) - return "New chunk size does not" - " divide component size"; + if (info->component_size % (info->new_chunk/512)) { + unsigned long long shrink = info->component_size; + shrink &= ~(unsigned long long)(info->new_chunk/512-1); + pr_err("New chunk size (%dK) does not evenly divide device size (%lluk)\n", + info->new_chunk/1024, info->component_size/2); + pr_err("After shrinking any filesystem, \"mdadm --grow %s --size %llu\"\n", + devname, shrink/2); + pr_err("will shrink the array so the given chunk size would work.\n"); + return ""; + } break; default: return "chunk size not meaningful for this level"; @@ -2775,7 +2782,7 @@ static int reshape_array(char *container, int fd, char *devname, info->new_level = UnSet; if (info->delta_disks > 0) info->array.raid_disks -= info->delta_disks; - msg = analyse_change(info, &reshape); + msg = analyse_change(devname, info, &reshape); info->new_level = new_level; if (info->delta_disks > 0) info->array.raid_disks += info->delta_disks; @@ -2783,9 +2790,11 @@ static int reshape_array(char *container, int fd, char *devname, /* Make sure the array isn't read-only */ ioctl(fd, RESTART_ARRAY_RW, 0); } else - msg = analyse_change(info, &reshape); + msg = analyse_change(devname, info, &reshape); if (msg) { - pr_err("%s\n", msg); + /* if msg == "", error has already been printed */ + if (msg[0]) + pr_err("%s\n", msg); goto release; } if (restart && |