| From 1217e1d1999ed6c9c1e1b1acae0a74ab70464ae2 Mon Sep 17 00:00:00 2001 |
| From: NeilBrown <neilb@suse.com> |
| Date: Fri, 28 Oct 2016 15:59:41 +1100 |
| Subject: md: be careful not lot leak internal curr_resync value into metadata. -- (all) |
| |
| From: NeilBrown <neilb@suse.com> |
| |
| commit 1217e1d1999ed6c9c1e1b1acae0a74ab70464ae2 upstream. |
| |
| mddev->curr_resync usually records where the current resync is up to, |
| but during the starting phase it has some "magic" values. |
| |
| 1 - means that the array is trying to start a resync, but has yielded |
| to another array which shares physical devices, and also needs to |
| start a resync |
| 2 - means the array is trying to start resync, but has found another |
| array which shares physical devices and has already started resync. |
| |
| 3 - means that resync has commensed, but it is possible that nothing |
| has actually been resynced yet. |
| |
| It is important that this value not be visible to user-space and |
| particularly that it doesn't get written to the metadata, as the |
| resync or recovery checkpoint. In part, this is because it may be |
| slightly higher than the correct value, though this is very rare. |
| In part, because it is not a multiple of 4K, and some devices only |
| support 4K aligned accesses. |
| |
| There are two places where this value is propagates into either |
| ->curr_resync_completed or ->recovery_cp or ->recovery_offset. |
| These currently avoid the propagation of values 1 and 3, but will |
| allow 3 to leak through. |
| |
| Change them to only propagate the value if it is > 3. |
| |
| As this can cause an array to fail, the patch is suitable for -stable. |
| |
| Reported-by: Viswesh <viswesh.vichu@gmail.com> |
| Signed-off-by: NeilBrown <neilb@suse.com> |
| Signed-off-by: Shaohua Li <shli@fb.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/md.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/md/md.c |
| +++ b/drivers/md/md.c |
| @@ -8120,14 +8120,14 @@ void md_do_sync(struct md_thread *thread |
| |
| if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && |
| !test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
| - mddev->curr_resync > 2) { |
| + mddev->curr_resync > 3) { |
| mddev->curr_resync_completed = mddev->curr_resync; |
| sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
| } |
| mddev->pers->sync_request(mddev, max_sectors, &skipped); |
| |
| if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && |
| - mddev->curr_resync > 2) { |
| + mddev->curr_resync > 3) { |
| if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
| if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
| if (mddev->curr_resync >= mddev->recovery_cp) { |