|
@@ -2089,6 +2089,14 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
|
|
unsigned long cpu;
|
|
unsigned long cpu;
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Never shrink. And mddev_suspend() could deadlock if this is called
|
|
|
|
+ * from raid5d. In that case, scribble_disks and scribble_sectors
|
|
|
|
+ * should equal to new_disks and new_sectors
|
|
|
|
+ */
|
|
|
|
+ if (conf->scribble_disks >= new_disks &&
|
|
|
|
+ conf->scribble_sectors >= new_sectors)
|
|
|
|
+ return 0;
|
|
mddev_suspend(conf->mddev);
|
|
mddev_suspend(conf->mddev);
|
|
get_online_cpus();
|
|
get_online_cpus();
|
|
for_each_present_cpu(cpu) {
|
|
for_each_present_cpu(cpu) {
|
|
@@ -2110,6 +2118,10 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
|
|
}
|
|
}
|
|
put_online_cpus();
|
|
put_online_cpus();
|
|
mddev_resume(conf->mddev);
|
|
mddev_resume(conf->mddev);
|
|
|
|
+ if (!err) {
|
|
|
|
+ conf->scribble_disks = new_disks;
|
|
|
|
+ conf->scribble_sectors = new_sectors;
|
|
|
|
+ }
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6413,6 +6425,12 @@ static int raid5_alloc_percpu(struct r5conf *conf)
|
|
}
|
|
}
|
|
put_online_cpus();
|
|
put_online_cpus();
|
|
|
|
|
|
|
|
+ if (!err) {
|
|
|
|
+ conf->scribble_disks = max(conf->raid_disks,
|
|
|
|
+ conf->previous_raid_disks);
|
|
|
|
+ conf->scribble_sectors = max(conf->chunk_sectors,
|
|
|
|
+ conf->prev_chunk_sectors);
|
|
|
|
+ }
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|