diff options
| author | NeilBrown <neilb@suse.com> | 2015-09-24 00:00:51 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.com> | 2015-10-02 03:23:43 -0400 |
| commit | 88724bfa68be792c1487d759e87568c36ac1a1cc (patch) | |
| tree | 12cf787a5922610396529d90ae82ccaf223a57d9 | |
| parent | bcee19f424a0d8c26ecf2607b73c690802658b29 (diff) | |
md: wait for pending superblock updates before switching to read-only
If a superblock update is pending, wait for it to complete before
letting md_set_readonly() switch to readonly.
Otherwise we might lose important information about a device having
failed.
For external arrays, waiting for superblock updates can wait on
user-space, so in that case, just return an error.
Reported-and-tested-by: Shaohua Li <shli@fb.com>
Signed-off-by: NeilBrown <neilb@suse.com>
| -rw-r--r-- | drivers/md/md.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4f5ecbe94ccb..b8247bc32cf6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -5409,9 +5409,13 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) | |||
| 5409 | * which will now never happen */ | 5409 | * which will now never happen */ |
| 5410 | wake_up_process(mddev->sync_thread->tsk); | 5410 | wake_up_process(mddev->sync_thread->tsk); |
| 5411 | 5411 | ||
| 5412 | if (mddev->external && test_bit(MD_CHANGE_PENDING, &mddev->flags)) | ||
| 5413 | return -EBUSY; | ||
| 5412 | mddev_unlock(mddev); | 5414 | mddev_unlock(mddev); |
| 5413 | wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING, | 5415 | wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING, |
| 5414 | &mddev->recovery)); | 5416 | &mddev->recovery)); |
| 5417 | wait_event(mddev->sb_wait, | ||
| 5418 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
| 5415 | mddev_lock_nointr(mddev); | 5419 | mddev_lock_nointr(mddev); |
| 5416 | 5420 | ||
| 5417 | mutex_lock(&mddev->open_mutex); | 5421 | mutex_lock(&mddev->open_mutex); |
