summaryrefslogtreecommitdiff
path: root/Grow.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-06-24 13:02:35 +1000
committerNeilBrown <neilb@suse.de>2013-06-24 13:02:35 +1000
commita6a78630acd3772b493c042c71fc8c22799fab4d (patch)
tree402d2c88c7d79b4dfb054be198bb24a2a9436f0c /Grow.c
parent534f543296e6e28d44bb1176eb37258e8a542dc5 (diff)
Grow: Try hard to set new_offset.
Setting new_offset can fail if the v1.x "data_size" is too small. So if that happens, try increasing it first by writing "0". That can fail on spare devices due to a kernel bug, so if it doesn't try writing the correct number of sectors. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r--Grow.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/Grow.c b/Grow.c
index 122ca0ec..556bdafe 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2353,10 +2353,21 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
sd->data_offset - min);
}
}
- if (sysfs_set_num(sra, sd, "new_offset",
- new_data_offset) < 0) {
- err = errno;
- err = -1;
+ err = sysfs_set_num(sra, sd, "new_offset", new_data_offset);
+ if (err < 0 && errno == E2BIG) {
+ /* try again after increasing data size to max */
+ err = sysfs_set_num(sra, sd, "size", 0);
+ if (err < 0 && errno == EINVAL &&
+ !(sd->disk.state & (1<<MD_DISK_SYNC))) {
+ /* some kernels have a bug where you cannot
+ * use '0' on spare devices. */
+ sysfs_set_num(sra, sd, "size",
+ (sra->component_size + after)/2);
+ }
+ err = sysfs_set_num(sra, sd, "new_offset",
+ new_data_offset);
+ }
+ if (err < 0) {
if (errno == E2BIG && data_offset != INVALID_SECTORS) {
pr_err("data-offset is too big for %s\n",
dn);