diff options
author | NeilBrown <neilb@suse.de> | 2021-02-26 02:02:36 +0100 |
---|---|---|
committer | Jes Sorensen <jsorensen@fb.com> | 2021-03-03 15:29:17 +0100 |
commit | 8818d4e7fe7cda900d5c00014b05cdde058bdd29 (patch) | |
tree | 12dd72a08884c1c853d0041f7acbd19869315a2b /Grow.c | |
parent | mdadm: fix reshape from RAID5 to RAID6 with backup file (diff) | |
download | mdadm-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.c | 15 |
1 files changed, 12 insertions, 3 deletions
@@ -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); |