summaryrefslogtreecommitdiff
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2015-06-17 12:31:46 +1000
committerNeilBrown <neilb@suse.de>2015-06-25 17:16:49 +1000
commitab16bfc732c436658d13455f28b0b4a2608a7476 (patch)
tree8759fd4e6003feb01a0dd371f05e0b289f737349 /drivers/md/md.c
parent9a8c0fa861e4db60409b4dda254cef5e17e4d43c (diff)
md: clear Blocked flag on failed devices when array is read-only.
The Blocked flag indicates that a device has failed but that this fact hasn't been recorded in the metadata yet. Writes to such devices cannot be allowed until the metadata has been updated. On a read-only array, the Blocked flag will never be cleared. This prevents the device being removed from the array. If the metadata is being handled by the kernel (i.e. !mddev->external), then we can be sure that if the array is switch to writable, then a metadata update will happen and will record the failure. So we don't need the flag set. If metadata is externally managed, it is upto the external manager to clear the 'blocked' flag. Reported-by: XiaoNi <xni@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5fcce7371ee9..202deb43b822 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8130,6 +8130,15 @@ void md_check_recovery(struct mddev *mddev)
int spares = 0;
if (mddev->ro) {
+ struct md_rdev *rdev;
+ if (!mddev->external && mddev->in_sync)
+ /* 'Blocked' flag not needed as failed devices
+ * will be recorded if array switched to read/write.
+ * Leaving it set will prevent the device
+ * from being removed.
+ */
+ rdev_for_each(rdev, mddev)
+ clear_bit(Blocked, &rdev->flags);
/* On a read-only array we can:
* - remove failed devices
* - add already-in_sync devices if the array itself