summaryrefslogtreecommitdiff
path: root/Grow.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-06-27 10:12:31 +1000
committerNeilBrown <neilb@suse.de>2013-06-27 10:12:31 +1000
commita73b00811cf8b0c36bcf66c356951857fb37ce77 (patch)
tree9e4fdac6d39bbe2393e69c38887e1a6896a20acb /Grow.c
parentb379508eeb26273f6044080788ffa1eb257c96f4 (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.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/Grow.c b/Grow.c
index 35584cd9..d939850c 100644
--- a/Grow.c
+++ b/Grow.c
@@ -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 &&