diff options
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 2 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_state.c | 5 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 16 |
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); |