md: remove ability to explicit set an inactive array to 'clean'.
authorNeilBrown <neilb@suse.de>
Thu, 7 May 2009 02:50:57 +0000 (12:50 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 7 May 2009 02:50:57 +0000 (12:50 +1000)
Being able to write 'clean' to an 'array_state' of an inactive array
to activate it in 'clean' mode is both unnecessary and inconvenient.

It is unnecessary because the same can be achieved by writing
'active'.  This activates and array, but it still remains 'clean'
until the first write.

It is inconvenient because writing 'clean' is more often used to
cause an 'active' array to revert to 'clean' mode (thus blocking
any writes until a 'write-pending' is promoted to 'active').

Allowing 'clean' to both activate an array and mark an active array as
clean can lead to races:  One program writes 'clean' to mark the
active array as clean at the same time as another program writes
'inactive' to deactivate (stop) and active array.  Depending on which
writes first, the array could be deactivated and immediately
reactivated which isn't what was desired.

So just disable the use of 'clean' to activate an array.

This avoids a race that can be triggered with mdadm-3.0 and external
metadata, so it suitable for -stable.

Reported-by: Rafal Marszewski <rafal.marszewski@intel.com>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Cc: <stable@kernel.org>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/md.c

index 8350bde60d1bdea8e44bba10b0e524e8e60efc7b..1dd723d31882626091a2c58c0e57567c21a5b4a4 100644 (file)
@@ -3066,11 +3066,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                        } else
                                err = -EBUSY;
                        spin_unlock_irq(&mddev->write_lock);
-               } else {
-                       mddev->ro = 0;
-                       mddev->recovery_cp = MaxSector;
-                       err = do_md_run(mddev);
-               }
+               } else
+                       err = -EINVAL;
                break;
        case active:
                if (mddev->pers) {