diff options
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 1599a1a6f1f7..a9eccfc6079b 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1037,6 +1037,16 @@ randomize: 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) |