aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/drbd/drbd_main.c6
-rw-r--r--drivers/block/drbd/drbd_nl.c2
-rw-r--r--drivers/block/drbd/drbd_state.c5
-rw-r--r--drivers/block/drbd/drbd_worker.c16
4 files changed, 26 insertions, 3 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index edd0227f4b43..822fb3d42356 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1087,7 +1087,11 @@ void drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev)
1087 1087
1088 D_ASSERT(mdev->state.disk == D_UP_TO_DATE); 1088 D_ASSERT(mdev->state.disk == D_UP_TO_DATE);
1089 1089
1090 uuid = mdev->ldev->md.uuid[UI_BITMAP] + UUID_NEW_BM_OFFSET; 1090 uuid = mdev->ldev->md.uuid[UI_BITMAP];
1091 if (uuid && uuid != UUID_JUST_CREATED)
1092 uuid = uuid + UUID_NEW_BM_OFFSET;
1093 else
1094 get_random_bytes(&uuid, sizeof(u64));
1091 drbd_uuid_set(mdev, UI_BITMAP, uuid); 1095 drbd_uuid_set(mdev, UI_BITMAP, uuid);
1092 drbd_print_uuids(mdev, "updated sync UUID"); 1096 drbd_print_uuids(mdev, "updated sync UUID");
1093 drbd_md_sync(mdev); 1097 drbd_md_sync(mdev);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 16c3710e1b9c..c50c1753aa9a 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1666,7 +1666,9 @@ static int adm_detach(struct drbd_conf *mdev, int force)
1666 } 1666 }
1667 1667
1668 drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ 1668 drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */
1669 drbd_md_get_buffer(mdev); /* make sure there is no in-flight meta-data IO */
1669 retcode = drbd_request_state(mdev, NS(disk, D_FAILED)); 1670 retcode = drbd_request_state(mdev, NS(disk, D_FAILED));
1671 drbd_md_put_buffer(mdev);
1670 /* D_FAILED will transition to DISKLESS. */ 1672 /* D_FAILED will transition to DISKLESS. */
1671 ret = wait_event_interruptible(mdev->misc_wait, 1673 ret = wait_event_interruptible(mdev->misc_wait,
1672 mdev->state.disk != D_FAILED); 1674 mdev->state.disk != D_FAILED);
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 4075bd2d2515..dffc6973e2b5 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1231,6 +1231,11 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1231 } 1231 }
1232 1232
1233 if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { 1233 if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) {
1234 if (os.peer == R_SECONDARY && ns.peer == R_PRIMARY &&
1235 mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
1236 drbd_uuid_new_current(mdev);
1237 drbd_send_uuids(mdev);
1238 }
1234 /* D_DISKLESS Peer becomes secondary */ 1239 /* D_DISKLESS Peer becomes secondary */
1235 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) 1240 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
1236 /* We may still be Primary ourselves. 1241 /* We may still be Primary ourselves.
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 34a6065d95e6..bc2cfd6c600f 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -74,10 +74,21 @@ void drbd_md_io_complete(struct bio *bio, int error)
74 74
75 md_io->error = error; 75 md_io->error = error;
76 76
77 /* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
78 * to timeout on the lower level device, and eventually detach from it.
79 * If this io completion runs after that timeout expired, this
80 * drbd_md_put_buffer() may allow us to finally try and re-attach.
81 * During normal operation, this only puts that extra reference
82 * down to 1 again.
83 * Make sure we first drop the reference, and only then signal
84 * completion, or we may (in drbd_al_read_log()) cycle so fast into the
85 * next drbd_md_sync_page_io(), that we trigger the
86 * ASSERT(atomic_read(&mdev->md_io_in_use) == 1) there.
87 */
88 drbd_md_put_buffer(mdev);
77 md_io->done = 1; 89 md_io->done = 1;
78 wake_up(&mdev->misc_wait); 90 wake_up(&mdev->misc_wait);
79 bio_put(bio); 91 bio_put(bio);
80 drbd_md_put_buffer(mdev);
81 put_ldev(mdev); 92 put_ldev(mdev);
82} 93}
83 94
@@ -1581,12 +1592,13 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
1581 } 1592 }
1582 clear_bit(B_RS_H_DONE, &mdev->flags); 1593 clear_bit(B_RS_H_DONE, &mdev->flags);
1583 1594
1595 write_lock_irq(&global_state_lock);
1584 if (!get_ldev_if_state(mdev, D_NEGOTIATING)) { 1596 if (!get_ldev_if_state(mdev, D_NEGOTIATING)) {
1597 write_unlock_irq(&global_state_lock);
1585 mutex_unlock(mdev->state_mutex); 1598 mutex_unlock(mdev->state_mutex);
1586 return; 1599 return;
1587 } 1600 }
1588 1601
1589 write_lock_irq(&global_state_lock);
1590 ns = drbd_read_state(mdev); 1602 ns = drbd_read_state(mdev);
1591 1603
1592 ns.aftr_isp = !_drbd_may_sync_now(mdev); 1604 ns.aftr_isp = !_drbd_may_sync_now(mdev);