drbd: Do not send two barriers without any writes between them
Philipp Reisner [Tue, 22 Jun 2010 09:26:48 +0000 (11:26 +0200)]
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>

drivers/block/drbd/drbd_main.c

index a8a0341..7d35986 100644 (file)
@@ -344,7 +344,7 @@ bail:
 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 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
        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 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
                }
                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 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
                        }
                        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 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
                                /* 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 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
                        kfree(b);
                }
                b = tmp;
+               list_splice(&carry_reads, &b->requests);
        }
 }