Commit 5e7dd2ab6b9bdfa60e19b8739e6b2a204fd4f477
Committed by
Linus Torvalds
1 parent
62de608da0
Exists in
master
and in
7 other branches
[PATCH] md: Fix 'rdev->nr_pending' count when retrying barrier requests
When retrying a failed BIO_RW_BARRIER request, we need to keep the reference in ->nr_pending over the whole retry. Currently, we only hold the reference if the failed request is the *last* one to finish - which is silly, because it would normally be the first to finish. So move the rdev_dec_pending call up into the didn't-fail branch. As the rdev isn't used in the later code, calling rdev_dec_pending earlier doesn't hurt. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 4 additions and 5 deletions Side-by-side Diff
drivers/md/raid1.c
... | ... | @@ -319,6 +319,7 @@ |
319 | 319 | set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); |
320 | 320 | set_bit(R1BIO_BarrierRetry, &r1_bio->state); |
321 | 321 | r1_bio->mddev->barriers_work = 0; |
322 | + /* Don't rdev_dec_pending in this branch - keep it for the retry */ | |
322 | 323 | } else { |
323 | 324 | /* |
324 | 325 | * this branch is our 'one mirror IO has finished' event handler: |
... | ... | @@ -365,6 +366,7 @@ |
365 | 366 | } |
366 | 367 | } |
367 | 368 | } |
369 | + rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | |
368 | 370 | } |
369 | 371 | /* |
370 | 372 | * |
371 | 373 | |
... | ... | @@ -374,11 +376,9 @@ |
374 | 376 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
375 | 377 | if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { |
376 | 378 | reschedule_retry(r1_bio); |
377 | - /* Don't dec_pending yet, we want to hold | |
378 | - * the reference over the retry | |
379 | - */ | |
380 | 379 | goto out; |
381 | 380 | } |
381 | + /* it really is the end of this request */ | |
382 | 382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { |
383 | 383 | /* free extra copy of the data pages */ |
384 | 384 | int i = bio->bi_vcnt; |
... | ... | @@ -393,8 +393,6 @@ |
393 | 393 | md_write_end(r1_bio->mddev); |
394 | 394 | raid_end_bio_io(r1_bio); |
395 | 395 | } |
396 | - | |
397 | - rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | |
398 | 396 | out: |
399 | 397 | if (to_put) |
400 | 398 | bio_put(to_put); |
... | ... | @@ -1414,6 +1412,7 @@ |
1414 | 1412 | * Better resubmit without the barrier. |
1415 | 1413 | * We know which devices to resubmit for, because |
1416 | 1414 | * all others have had their bios[] entry cleared. |
1415 | + * We already have a nr_pending reference on these rdevs. | |
1417 | 1416 | */ |
1418 | 1417 | int i; |
1419 | 1418 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |