diff --git a/[refs] b/[refs] index 5f636a3f49a4..c689a283423a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 691631c0652bc47e6d20b0d981e23a9025fd794e +refs/heads/master: 13c76aba7846647f86d479293ae0a0adc1ca840a diff --git a/trunk/drivers/block/drbd/drbd_receiver.c b/trunk/drivers/block/drbd/drbd_receiver.c index 1599a1a6f1f7..a9eccfc6079b 100644 --- a/trunk/drivers/block/drbd/drbd_receiver.c +++ b/trunk/drivers/block/drbd/drbd_receiver.c @@ -1037,6 +1037,16 @@ static int conn_connect(struct drbd_tconn *tconn) rcu_read_lock(); idr_for_each_entry(&tconn->volumes, mdev, vnr) { kref_get(&mdev->kref); + /* Prevent a race between resync-handshake and + * being promoted to Primary. + * + * Grab and release the state mutex, so we know that any current + * drbd_set_role() is finished, and any incoming drbd_set_role + * will see the STATE_SENT flag, and wait for it to be cleared. + */ + mutex_lock(mdev->state_mutex); + mutex_unlock(mdev->state_mutex); + rcu_read_unlock(); if (discard_my_data)