drbd: fix race on meta-data update
authorLars Ellenberg <lars.ellenberg@linbit.com>
Wed, 1 Sep 2010 13:12:12 +0000 (15:12 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 14 Oct 2010 16:38:28 +0000 (18:38 +0200)
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>
drivers/block/drbd/drbd_main.c

index 23878ffc43c8ac588ea4060e83d38724eff02a7d..73c905d0ef181bd95e0298ccf0d5aaa2dc73209d 100644 (file)
@@ -3446,12 +3446,9 @@ void drbd_md_sync(struct drbd_conf *mdev)
        D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset);
        sector = mdev->ldev->md.md_offset;
 
-       if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
-               clear_bit(MD_DIRTY, &mdev->flags);
-       } else {
+       if (!drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
                /* this was a try anyways ... */
                dev_err(DEV, "meta data update failed!\n");
-
                drbd_chk_io_error(mdev, 1, TRUE);
        }