summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-06-22 11:26:48 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 14:36:51 +0200
commitb9b98716f83856b928f1c985ab55520c67663dd2 (patch)
treed935bc8efc8a7ecc6a05225ff941a16ee1d8bfcf /drivers/block
parent11b58e73a3a3d1bbb582370d59f9b2c4d0136b42 (diff)
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>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_main.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a8a0341fce53..7d359863ae32 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -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);
}
}