diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-04-25 10:27:35 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-05-09 09:16:59 -0400 |
commit | a574daf5d722f4ca8cc18509f30b804c4d519962 (patch) | |
tree | 83ae95ce9a57d605ce2a308ceb2a026e9f2ca9b2 /drivers/block/drbd | |
parent | ba280c092e6eca8a70c502e4510061535fdce382 (diff) |
drbd: fix race between drbdadm invalidate/verify and finishing resync
When a resync or online verify is finished or aborted,
drbd does a bulk write-out of changed bitmap pages.
If *in that very moment* a new verify or resync is triggered,
this can race:
ASSERT( !test_bit(BITMAP_IO, &mdev->flags) ) in drbd_main.c
FIXME going to queue 'set_n_write from StartingSync' but 'write from resync_finished' still pending?
and similar.
This can be observed with e.g. tight invalidate loops in test scripts,
and probably has no real-life implication.
Still, that race can be solved by first quiescen the device,
before starting a new resync or verify.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 308beb8c0c1e..867bf1d82988 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1963,6 +1963,7 @@ static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl | |||
1963 | 1963 | ||
1964 | /* If there is still bitmap IO pending, probably because of a previous | 1964 | /* If there is still bitmap IO pending, probably because of a previous |
1965 | * resync just being finished, wait for it before requesting a new resync. */ | 1965 | * resync just being finished, wait for it before requesting a new resync. */ |
1966 | drbd_suspend_io(mdev); | ||
1966 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); | 1967 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); |
1967 | 1968 | ||
1968 | retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T), CS_ORDERED); | 1969 | retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T), CS_ORDERED); |
@@ -1981,6 +1982,7 @@ static int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl | |||
1981 | 1982 | ||
1982 | retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T)); | 1983 | retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_T)); |
1983 | } | 1984 | } |
1985 | drbd_resume_io(mdev); | ||
1984 | 1986 | ||
1985 | reply->ret_code = retcode; | 1987 | reply->ret_code = retcode; |
1986 | return 0; | 1988 | return 0; |
@@ -2002,6 +2004,7 @@ static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_re | |||
2002 | 2004 | ||
2003 | /* If there is still bitmap IO pending, probably because of a previous | 2005 | /* If there is still bitmap IO pending, probably because of a previous |
2004 | * resync just being finished, wait for it before requesting a new resync. */ | 2006 | * resync just being finished, wait for it before requesting a new resync. */ |
2007 | drbd_suspend_io(mdev); | ||
2005 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); | 2008 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); |
2006 | 2009 | ||
2007 | retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S), CS_ORDERED); | 2010 | retcode = _drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S), CS_ORDERED); |
@@ -2020,6 +2023,7 @@ static int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_re | |||
2020 | } else | 2023 | } else |
2021 | retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S)); | 2024 | retcode = drbd_request_state(mdev, NS(conn, C_STARTING_SYNC_S)); |
2022 | } | 2025 | } |
2026 | drbd_resume_io(mdev); | ||
2023 | 2027 | ||
2024 | reply->ret_code = retcode; | 2028 | reply->ret_code = retcode; |
2025 | return 0; | 2029 | return 0; |
@@ -2192,11 +2196,13 @@ static int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, | |||
2192 | 2196 | ||
2193 | /* If there is still bitmap IO pending, e.g. previous resync or verify | 2197 | /* If there is still bitmap IO pending, e.g. previous resync or verify |
2194 | * just being finished, wait for it before requesting a new resync. */ | 2198 | * just being finished, wait for it before requesting a new resync. */ |
2199 | drbd_suspend_io(mdev); | ||
2195 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); | 2200 | wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags)); |
2196 | 2201 | ||
2197 | /* w_make_ov_request expects position to be aligned */ | 2202 | /* w_make_ov_request expects position to be aligned */ |
2198 | mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT; | 2203 | mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT; |
2199 | reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S)); | 2204 | reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S)); |
2205 | drbd_resume_io(mdev); | ||
2200 | return 0; | 2206 | return 0; |
2201 | } | 2207 | } |
2202 | 2208 | ||