aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/drbd/drbd_main.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9bd53cf2cdb2..90050ab7adf3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -335,6 +335,24 @@ bail:
335 drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR)); 335 drbd_force_state(mdev, NS(conn, C_PROTOCOL_ERROR));
336} 336}
337 337
338
339/* In C_AHEAD mode only out_of_sync packets are sent for requests. Detach
340 * those requests from the newsest barrier when changing to an other cstate.
341 *
342 * That headless list vanishes when the last request finished its write or
343 * send out_of_sync packet. */
344static void tl_forget(struct drbd_conf *mdev)
345{
346 struct drbd_tl_epoch *b;
347
348 if (test_bit(CREATE_BARRIER, &mdev->flags))
349 return;
350
351 b = mdev->newest_tle;
352 list_del(&b->requests);
353 _tl_add_barrier(mdev, b);
354}
355
338/** 356/**
339 * _tl_restart() - Walks the transfer log, and applies an action to all requests 357 * _tl_restart() - Walks the transfer log, and applies an action to all requests
340 * @mdev: DRBD device. 358 * @mdev: DRBD device.
@@ -1242,6 +1260,9 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
1242 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) 1260 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
1243 drbd_resume_al(mdev); 1261 drbd_resume_al(mdev);
1244 1262
1263 if (os.conn == C_AHEAD && ns.conn != C_AHEAD)
1264 tl_forget(mdev);
1265
1245 ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); 1266 ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
1246 if (ascw) { 1267 if (ascw) {
1247 ascw->os = os; 1268 ascw->os = os;