drbd: Be more careful with SyncSource -> Ahead transitions

We may not get from SyncSource to Ahead if we have sent some
P_RS_DATA_REPLY packets to the peer and are waiting for
P_WRITE_ACK.

Again, this is not relevant for proper tuned systems, but makes
sure that the not-tuned system does not get diverging bitmaps.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
Philipp Reisner 2010-12-23 14:24:33 +01:00
parent d612d309e4
commit da0a78161d
2 changed files with 9 additions and 2 deletions

View File

@ -4385,10 +4385,11 @@ static int got_BarrierAck(struct drbd_conf *mdev, struct p_header80 *h)
if (mdev->state.conn == C_AHEAD &&
atomic_read(&mdev->ap_in_flight) == 0 &&
atomic_read(&mdev->rs_pending_cnt) == 0 &&
list_empty(&mdev->start_resync_work.list)) {
struct drbd_work *w = &mdev->start_resync_work;
w->cb = w_start_resync;
drbd_queue_work_front(&mdev->data.work, w);
drbd_queue_work(&mdev->data.work, w);
}
return true;

View File

@ -1002,7 +1002,13 @@ allocate_barrier:
congested = 1;
}
if (congested) {
if (congested && atomic_read(&mdev->rs_pending_cnt) == 0) {
/* rs_pending_cnt must be zero, otherwise the two peers
might get different bitmaps. With sane configurations
the resync stalls long before we might want to go into
AHEAD mode.
We could force the resync into PAUSE mode here if
rs_pending_cnt is > 0 ... */
queue_barrier(mdev);
if (mdev->net_conf->on_congestion == OC_PULL_AHEAD)