aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-06-22 05:26:48 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 08:36:51 -0400
commitb9b98716f83856b928f1c985ab55520c67663dd2 (patch)
treed935bc8efc8a7ecc6a05225ff941a16ee1d8bfcf /drivers/block/drbd/drbd_main.c
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/drbd/drbd_main.c')
-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:
344static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) 344static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
345{ 345{
346 struct drbd_tl_epoch *b, *tmp, **pn; 346 struct drbd_tl_epoch *b, *tmp, **pn;
347 struct list_head *le, *tle; 347 struct list_head *le, *tle, carry_reads;
348 struct drbd_request *req; 348 struct drbd_request *req;
349 int rv, n_writes, n_reads; 349 int rv, n_writes, n_reads;
350 350
@@ -353,6 +353,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
353 while (b) { 353 while (b) {
354 n_writes = 0; 354 n_writes = 0;
355 n_reads = 0; 355 n_reads = 0;
356 INIT_LIST_HEAD(&carry_reads);
356 list_for_each_safe(le, tle, &b->requests) { 357 list_for_each_safe(le, tle, &b->requests) {
357 req = list_entry(le, struct drbd_request, tl_requests); 358 req = list_entry(le, struct drbd_request, tl_requests);
358 rv = _req_mod(req, what); 359 rv = _req_mod(req, what);
@@ -362,7 +363,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
362 } 363 }
363 tmp = b->next; 364 tmp = b->next;
364 365
365 if (n_writes + n_reads) { 366 if (n_writes) {
366 if (what == resend) { 367 if (what == resend) {
367 b->n_writes = n_writes; 368 b->n_writes = n_writes;
368 if (b->w.cb == NULL) { 369 if (b->w.cb == NULL) {
@@ -375,6 +376,8 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
375 } 376 }
376 pn = &b->next; 377 pn = &b->next;
377 } else { 378 } else {
379 if (n_reads)
380 list_add(&carry_reads, &b->requests);
378 /* there could still be requests on that ring list, 381 /* there could still be requests on that ring list,
379 * in case local io is still pending */ 382 * in case local io is still pending */
380 list_del(&b->requests); 383 list_del(&b->requests);
@@ -389,6 +392,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
389 /* recycle, but reinit! */ 392 /* recycle, but reinit! */
390 D_ASSERT(tmp == NULL); 393 D_ASSERT(tmp == NULL);
391 INIT_LIST_HEAD(&b->requests); 394 INIT_LIST_HEAD(&b->requests);
395 list_splice(&carry_reads, &b->requests);
392 INIT_LIST_HEAD(&b->w.list); 396 INIT_LIST_HEAD(&b->w.list);
393 b->w.cb = NULL; 397 b->w.cb = NULL;
394 b->br_number = net_random(); 398 b->br_number = net_random();
@@ -401,6 +405,7 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)
401 kfree(b); 405 kfree(b);
402 } 406 }
403 b = tmp; 407 b = tmp;
408 list_splice(&carry_reads, &b->requests);
404 } 409 }
405} 410}
406 411