diff --git a/[refs] b/[refs] index cb486a591b7d..355a12fbc63e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 071942727824bab03b1a3f6b6eeb5b269697b333 +refs/heads/master: 617049aa7d753e8c821ac77126ab90e9f1b66d6d diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index 9bd53cf2cdb2..90050ab7adf3 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -335,6 +335,24 @@ void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR)); } + +/* In C_AHEAD mode only out_of_sync packets are sent for requests. Detach + * those requests from the newsest barrier when changing to an other cstate. + * + * That headless list vanishes when the last request finished its write or + * send out_of_sync packet. */ +static void tl_forget(struct drbd_conf *mdev) +{ + struct drbd_tl_epoch *b; + + if (test_bit(CREATE_BARRIER, &mdev->flags)) + return; + + b = mdev->newest_tle; + list_del(&b->requests); + _tl_add_barrier(mdev, b); +} + /** * _tl_restart() - Walks the transfer log, and applies an action to all requests * @mdev: DRBD device. @@ -1242,6 +1260,9 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) drbd_resume_al(mdev); + if (os.conn == C_AHEAD && ns.conn != C_AHEAD) + tl_forget(mdev); + ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); if (ascw) { ascw->os = os;