Patch "md: fix race when unfreezing sync_action" has been added to the 4.0-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
md: fix race when unfreezing sync_action
to the 4.0-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
md-fix-race-when-unfreezing-sync_action.patch
and it can be found in the queue-4.0 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
56ccc1125bc141cf63927eda7febff4216dea2d3Mon Sep 17 00:00:00 2001
From: NeilBrown <[email protected]>
Date: Thu, 28 May 2015 17:53:29 +1000
Subject: md: fix race when unfreezing sync_action
From: NeilBrown <[email protected]>
commit 56ccc1125bc141cf63927eda7febff4216dea2d3 upstream.
A recent change removed the need for locking around writing to "sync_action" (and various other places), but introduced a subtle race.
When e.g. setting 'reshape' on a 'frozen' array, the 'frozen' flag is cleared before 'reshape' is set, so the md thread can get in and start trying recovery - which isn't wanted.
So instead of clearing MD_RECOVERY_FROZEN for any command except 'frozen', only clear it when each specific command is parsed. This allows the handling of 'reshape' to clear the bit while a lock is held.
Also remove some places where we set MD_RECOVERY_NEEDED, as it is always set on non-error exit of the function.
--- drivers/md/md.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/md/md.c +8 -6
@@ -4138,12 +4138,12 @@ action_store(struct mddev *mddev, constif (!mddev->pers || !mddev->pers->sync_request)return -EINVAL ; -if (cmd_match (page,"frozen" )) -set_bit (MD_RECOVERY_FROZEN , &mddev->recovery); -else -clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery);if (cmd_match (page,"idle" ) ||cmd_match (page,"frozen" )) { +if (cmd_match (page,"frozen" )) +set_bit (MD_RECOVERY_FROZEN , &mddev->recovery); +else +clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery);flush_workqueue (md_misc_wq);if (mddev->sync_thread) {set_bit (MD_RECOVERY_INTR , &mddev->recovery);
@@ -4156,16 +4156,17 @@ action_store(struct mddev *mddev, const test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))return -EBUSY ; else if (cmd_match(page, "resync")) - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); else if (cmd_match(page, "recover")) { +clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery);set_bit (MD_RECOVERY_RECOVER , &mddev->recovery); -set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); } else if (cmd_match(page, "reshape")) {int err;if (mddev->pers->start_reshape ==NULL )return -EINVAL ; err =mddev_lock (mddev);if (!err) { +clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery); err = mddev->pers->start_reshape (mddev);mddev_unlock (mddev); }
@@ -4177,6 +4178,7 @@ action_store(struct mddev *mddev, constset_bit (MD_RECOVERY_CHECK , &mddev->recovery); else if (!cmd_match(page, "repair"))return -EINVAL ; +clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery);set_bit (MD_RECOVERY_REQUESTED , &mddev->recovery);set_bit (MD_RECOVERY_SYNC , &mddev->recovery); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.0/md-raid5-don-t-record-new-size-if-resize_stripes-fails.patch queue-4.0/md-raid0-fix-restore-to-sector-variable-in-raid0_make_request.patch queue-4.0/md-fix-race-when-unfreezing-sync_action.patch queue-4.0/sched-always-use-blk_schedule_flush_plug-in-io_schedule_out.patch