diff options
author | Doug Ledford <dledford@redhat.com> | 2011-09-19 05:06:38 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-09-19 05:06:38 +0200 |
commit | 16715c01f7ea4410d3b0eb3fe8bd66ab9241f036 (patch) | |
tree | 577cb4f71bc616f53ccd04b3e004bd152d06bae8 /Manage.c | |
parent | Monitor: --oneshot must imply --no-sharing (diff) | |
download | mdadm-16715c01f7ea4410d3b0eb3fe8bd66ab9241f036.tar.xz mdadm-16715c01f7ea4410d3b0eb3fe8bd66ab9241f036.zip |
Fix readding of a readwrite drive into a writemostly array
If you create a two drive raid1 array with one device writemostly, then
fail the readwrite drive, when you add a new device, it will get the
writemostly bit copied out of the remaining device's superblock into
it's own. You can then remove the new drive and readd it as readwrite,
which will work for the readd, but it leaves the stale WriteMostly1 bit
in devflags resulting in the device going back to writemostly on the
next assembly.
The fix is to make sure that A) when we readd a device and we might have
filled the st->sb info from a running device instead of the device being
readded, then clear/set the WriteMostly1 bit in the super1 struct in
addition to setting the disk state (ditto for super0, but slightly
different mechanism) and B) when adding a clean device to an array (when
we most certainly did copy the superblock info from an existing device),
then clear any writemostly bits.
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r-- | Manage.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -762,11 +762,24 @@ int Manage_subdevs(char *devname, int fd, remove_partitions(tfd); close(tfd); tfd = -1; - if (update) { + if (update || dv->writemostly > 0) { int rv = -1; tfd = dev_open(dv->devname, O_RDWR); + if (tfd < 0) { + fprintf(stderr, Name ": failed to open %s for" + " superblock update during re-add\n", dv->devname); + return 1; + } - if (tfd >= 0) + if (dv->writemostly == 1) + rv = st->ss->update_super( + st, NULL, "writemostly", + devname, verbose, 0, NULL); + if (dv->writemostly == 2) + rv = st->ss->update_super( + st, NULL, "readwrite", + devname, verbose, 0, NULL); + if (update) rv = st->ss->update_super( st, NULL, update, devname, verbose, 0, NULL); |