diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2010-09-01 09:12:12 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2010-10-14 12:38:28 -0400 |
commit | 3f3a9b849d2b703934c07fa17f5eac2dc37c1f6b (patch) | |
tree | 12aff51d5d92a0642232205b95eb9e55e85dd2bf /drivers | |
parent | c518d04fdec3d8b9d6f8b2228040934de9ee6708 (diff) |
drbd: fix race on meta-data update
The race:
drbd_md_mark_dirty()
drbd_md_sync()
if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
return;
drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)
==> RACE
clear_bit(MD_DIRTY, &mdev->flags); <== spurious
Fixed by removing the spurious clear_bit.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 23878ffc43c8..73c905d0ef18 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -3446,12 +3446,9 @@ void drbd_md_sync(struct drbd_conf *mdev) | |||
3446 | D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset); | 3446 | D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset); |
3447 | sector = mdev->ldev->md.md_offset; | 3447 | sector = mdev->ldev->md.md_offset; |
3448 | 3448 | ||
3449 | if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { | 3449 | if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { |
3450 | clear_bit(MD_DIRTY, &mdev->flags); | ||
3451 | } else { | ||
3452 | /* this was a try anyways ... */ | 3450 | /* this was a try anyways ... */ |
3453 | dev_err(DEV, "meta data update failed!\n"); | 3451 | dev_err(DEV, "meta data update failed!\n"); |
3454 | |||
3455 | drbd_chk_io_error(mdev, 1, TRUE); | 3452 | drbd_chk_io_error(mdev, 1, TRUE); |
3456 | } | 3453 | } |
3457 | 3454 | ||