diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/ll_rw_blk.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index dfe0948ec8b2..b55ed0df33f0 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -527,22 +527,36 @@ int blk_do_ordered(struct request_queue *q, struct request **rqp) | |||
527 | return 1; | 527 | return 1; |
528 | } | 528 | } |
529 | 529 | ||
530 | static int ordered_bio_endio(struct request *rq, struct bio *bio, | 530 | static void req_bio_endio(struct request *rq, struct bio *bio, |
531 | unsigned int nbytes, int error) | 531 | unsigned int nbytes, int error) |
532 | { | 532 | { |
533 | struct request_queue *q = rq->q; | 533 | struct request_queue *q = rq->q; |
534 | 534 | ||
535 | if (&q->bar_rq != rq) | 535 | if (&q->bar_rq != rq) { |
536 | return 0; | 536 | if (error) |
537 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
538 | else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) | ||
539 | error = -EIO; | ||
537 | 540 | ||
538 | /* | 541 | if (unlikely(nbytes > bio->bi_size)) { |
539 | * Okay, this is the barrier request in progress, just | 542 | printk("%s: want %u bytes done, only %u left\n", |
540 | * record the error; | 543 | __FUNCTION__, nbytes, bio->bi_size); |
541 | */ | 544 | nbytes = bio->bi_size; |
542 | if (error && !q->orderr) | 545 | } |
543 | q->orderr = error; | ||
544 | 546 | ||
545 | return 1; | 547 | bio->bi_size -= nbytes; |
548 | bio->bi_sector += (nbytes >> 9); | ||
549 | if (bio->bi_size == 0) | ||
550 | bio_endio(bio, bio->bi_size, error); | ||
551 | } else { | ||
552 | |||
553 | /* | ||
554 | * Okay, this is the barrier request in progress, just | ||
555 | * record the error; | ||
556 | */ | ||
557 | if (error && !q->orderr) | ||
558 | q->orderr = error; | ||
559 | } | ||
546 | } | 560 | } |
547 | 561 | ||
548 | /** | 562 | /** |
@@ -3388,8 +3402,7 @@ static int __end_that_request_first(struct request *req, int uptodate, | |||
3388 | if (nr_bytes >= bio->bi_size) { | 3402 | if (nr_bytes >= bio->bi_size) { |
3389 | req->bio = bio->bi_next; | 3403 | req->bio = bio->bi_next; |
3390 | nbytes = bio->bi_size; | 3404 | nbytes = bio->bi_size; |
3391 | if (!ordered_bio_endio(req, bio, nbytes, error)) | 3405 | req_bio_endio(req, bio, nbytes, error); |
3392 | bio_endio(bio, nbytes, error); | ||
3393 | next_idx = 0; | 3406 | next_idx = 0; |
3394 | bio_nbytes = 0; | 3407 | bio_nbytes = 0; |
3395 | } else { | 3408 | } else { |
@@ -3444,8 +3457,7 @@ static int __end_that_request_first(struct request *req, int uptodate, | |||
3444 | * if the request wasn't completed, update state | 3457 | * if the request wasn't completed, update state |
3445 | */ | 3458 | */ |
3446 | if (bio_nbytes) { | 3459 | if (bio_nbytes) { |
3447 | if (!ordered_bio_endio(req, bio, bio_nbytes, error)) | 3460 | req_bio_endio(req, bio, bio_nbytes, error); |
3448 | bio_endio(bio, bio_nbytes, error); | ||
3449 | bio->bi_idx += next_idx; | 3461 | bio->bi_idx += next_idx; |
3450 | bio_iovec(bio)->bv_offset += nr_bytes; | 3462 | bio_iovec(bio)->bv_offset += nr_bytes; |
3451 | bio_iovec(bio)->bv_len -= nr_bytes; | 3463 | bio_iovec(bio)->bv_len -= nr_bytes; |