Commit c1dd448e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] md: Split read and write end_request handlers

From: NeilBrown <neilb@cse.unsw.edu.au>

Instead of having a single end_request handler that must determine whether it
was a read or a write request, we have two separate handlers, which makes
each of them easier to follow.
parent a2c4e506
......@@ -261,7 +261,7 @@ static inline void update_head_pos(int disk, r1bio_t *r1_bio)
r1_bio->sector + (r1_bio->master_bio->bi_size >> 9);
}
static int raid1_end_request(struct bio *bio, unsigned int bytes_done, int error)
static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int error)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
......@@ -271,13 +271,7 @@ static int raid1_end_request(struct bio *bio, unsigned int bytes_done, int error
if (bio->bi_size)
return 1;
if (r1_bio->cmd == READ || r1_bio->cmd == READA)
mirror = r1_bio->read_disk;
else {
for (mirror = 0; mirror < conf->raid_disks; mirror++)
if (r1_bio->write_bios[mirror] == bio)
break;
}
/*
* this branch is our 'one mirror IO has finished' event handler:
*/
......@@ -296,7 +290,7 @@ static int raid1_end_request(struct bio *bio, unsigned int bytes_done, int error
set_bit(R1BIO_Uptodate, &r1_bio->state);
update_head_pos(mirror, r1_bio);
if ((r1_bio->cmd == READ) || (r1_bio->cmd == READA)) {
if (!r1_bio->read_bio)
BUG();
/*
......@@ -313,12 +307,47 @@ static int raid1_end_request(struct bio *bio, unsigned int bytes_done, int error
bdevname(conf->mirrors[mirror].rdev->bdev,b), (unsigned long long)r1_bio->sector);
reschedule_retry(r1_bio);
}
} else {
atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
return 0;
}
static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int error)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
int mirror;
conf_t *conf = mddev_to_conf(r1_bio->mddev);
if (bio->bi_size)
return 1;
for (mirror = 0; mirror < conf->raid_disks; mirror++)
if (r1_bio->write_bios[mirror] == bio)
break;
/*
* this branch is our 'one mirror IO has finished' event handler:
*/
if (!uptodate)
md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
else
/*
* Set R1BIO_Uptodate in our master bio, so that
* we will return a good error code for to the higher
* levels even if IO on some other mirrored buffer fails.
*
* The 'master' represents the composite IO operation to
* user-side. So if something waits for IO, then it will
* wait for the 'master' bio.
*/
set_bit(R1BIO_Uptodate, &r1_bio->state);
update_head_pos(mirror, r1_bio);
if (r1_bio->read_bio)
BUG();
/*
* WRITE:
*
* Let's see if all mirrored write operations have finished
* already.
......@@ -327,11 +356,12 @@ static int raid1_end_request(struct bio *bio, unsigned int bytes_done, int error
md_write_end(r1_bio->mddev);
raid_end_bio_io(r1_bio);
}
}
atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
return 0;
}
/*
* This routine returns the disk from which the requested read should
* be done. There is a per-array 'next expected sequential IO' sector
......@@ -508,7 +538,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_end_io = raid1_end_request;
read_bio->bi_end_io = raid1_end_read_request;
read_bio->bi_rw = r1_bio->cmd;
read_bio->bi_private = r1_bio;
......@@ -546,7 +576,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_request;
mbio->bi_end_io = raid1_end_write_request;
mbio->bi_rw = r1_bio->cmd;
mbio->bi_private = r1_bio;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment