summaryrefslogtreecommitdiffstats
path: root/Grow.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2021-02-26 02:02:36 +0100
committerJes Sorensen <jsorensen@fb.com>2021-03-03 15:29:17 +0100
commit8818d4e7fe7cda900d5c00014b05cdde058bdd29 (patch)
tree12dd72a08884c1c853d0041f7acbd19869315a2b /Grow.c
parentmdadm: fix reshape from RAID5 to RAID6 with backup file (diff)
downloadmdadm-8818d4e7fe7cda900d5c00014b05cdde058bdd29.tar.xz
mdadm-8818d4e7fe7cda900d5c00014b05cdde058bdd29.zip
Grow: be careful of corrupt dev_roles list
I've seen a case where the dev_roles list of a linear array was corrupt. ->max_dev was > 128 and > raid_disks, and the extra slots were '0', not 0xFFFE or 0xFFFF. This caused problems when a 128th device was added. So: 1/ make Grow_Add_device more robust so that if numbers look wrong, it fails-safe. 2/ make examine_super1() report details if the dev_roles array is corrupt. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Diffstat (limited to 'Grow.c')
-rw-r--r--Grow.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/Grow.c b/Grow.c
index 5c2512f6..cec83886 100644
--- a/Grow.c
+++ b/Grow.c
@@ -197,7 +197,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.disk.minor = minor(rdev);
info.disk.raid_disk = d;
info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
- st->ss->update_super(st, &info, "linear-grow-new", newdev, 0, 0, NULL);
+ if (st->ss->update_super(st, &info, "linear-grow-new", newdev,
+ 0, 0, NULL) != 0) {
+ pr_err("Preparing new metadata failed on %s\n", newdev);
+ close(nfd);
+ return 1;
+ }
if (st->ss->store_super(st, nfd)) {
pr_err("Cannot store new superblock on %s\n", newdev);
@@ -250,8 +255,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.array.active_disks = nd+1;
info.array.working_disks = nd+1;
- st->ss->update_super(st, &info, "linear-grow-update", dv,
- 0, 0, NULL);
+ if (st->ss->update_super(st, &info, "linear-grow-update", dv,
+ 0, 0, NULL) != 0) {
+ pr_err("Updating metadata failed on %s\n", dv);
+ close(fd2);
+ return 1;
+ }
if (st->ss->store_super(st, fd2)) {
pr_err("Cannot store new superblock on %s\n", dv);