drbd: Do not send two barriers without any writes between them

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a8a0341..7d35986 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -344,7 +344,7 @@
 static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
 {
 	struct drbd_tl_epoch *b, *tmp, **pn;
-	struct list_head *le, *tle;
+	struct list_head *le, *tle, carry_reads;
 	struct drbd_request *req;
 	int rv, n_writes, n_reads;
 
@@ -353,6 +353,7 @@
 	while (b) {
 		n_writes = 0;
 		n_reads = 0;
+		INIT_LIST_HEAD(&carry_reads);
 		list_for_each_safe(le, tle, &b->requests) {
 			req = list_entry(le, struct drbd_request, tl_requests);
 			rv = _req_mod(req, what);
@@ -362,7 +363,7 @@
 		}
 		tmp = b->next;
 
-		if (n_writes + n_reads) {
+		if (n_writes) {
 			if (what == resend) {
 				b->n_writes = n_writes;
 				if (b->w.cb == NULL) {
@@ -375,6 +376,8 @@
 			}
 			pn = &b->next;
 		} else {
+			if (n_reads)
+				list_add(&carry_reads, &b->requests);
 			/* there could still be requests on that ring list,
 			 * in case local io is still pending */
 			list_del(&b->requests);
@@ -389,6 +392,7 @@
 				/* recycle, but reinit! */
 				D_ASSERT(tmp == NULL);
 				INIT_LIST_HEAD(&b->requests);
+				list_splice(&carry_reads, &b->requests);
 				INIT_LIST_HEAD(&b->w.list);
 				b->w.cb = NULL;
 				b->br_number = net_random();
@@ -401,6 +405,7 @@
 			kfree(b);
 		}
 		b = tmp;
+		list_splice(&carry_reads, &b->requests);
 	}
 }