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 308beb8c0c1..867bf1d8298 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 | ||
