Skip to content

Commit 312045e

Browse files
author
NeilBrown
committed
md: remove check for MD_RECOVERY_NEEDED in action_store.
md currently doesn't allow a 'sync_action' such as 'reshape' to be set while MD_RECOVERY_NEEDED is set. This s a problem, particularly since commit 738a273 as that can cause ->check_shape to call mddev_resume() which sets MD_RECOVERY_NEEDED. So by the time we come to start 'reshape' it is very likely that MD_RECOVERY_NEEDED is still set. Testing for this flag is not really needed and is in any case very racy as it can be set at any moment - asynchronously. Any race between setting a sync_action and setting MD_RECOVERY_NEEDED must already be handled properly in some locked code, probably md_check_recovery(), so remove the test here. The test on MD_RECOVERY_RUNNING is also racy in the 'reshape' case so we should test it again after getting mddev_lock(). As this fixes a race and a regression which can cause 'reshape' to fail, it is suitable for -stable kernels since 4.1 Reported-by: Xiao Ni <[email protected]> Fixes: 738a273 ("md/raid5: fix allocation of 'scribble' array.") Cc: [email protected] (v4.1+) Signed-off-by: NeilBrown <[email protected]>
1 parent 9f7e432 commit 312045e

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/md/md.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,8 +4326,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
43264326
}
43274327
mddev_unlock(mddev);
43284328
}
4329-
} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
4330-
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
4329+
} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
43314330
return -EBUSY;
43324331
else if (cmd_match(page, "resync"))
43334332
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -4340,8 +4339,12 @@ action_store(struct mddev *mddev, const char *page, size_t len)
43404339
return -EINVAL;
43414340
err = mddev_lock(mddev);
43424341
if (!err) {
4343-
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
4344-
err = mddev->pers->start_reshape(mddev);
4342+
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
4343+
err = -EBUSY;
4344+
else {
4345+
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
4346+
err = mddev->pers->start_reshape(mddev);
4347+
}
43454348
mddev_unlock(mddev);
43464349
}
43474350
if (err)

0 commit comments

Comments
 (0)