Commit 1fbe06d4 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] clarify meaning of bio fields in the end_io function

From: Christophe Saout <christophe@saout.de>

The intent of these are to clarify the meaning of the bio fields in the
bi_end_io function (since we are already mostly there).  After these small
modifications bio->bi_idx and the corresponding bio_iovec(bio)->bv_offset
point to the beginning of the completed data, together with the nr_bytes
argument you know exactly what data was finished, e.g.  when you can't
track it otherwise (or it would be unnecessary expensive).  Apart from that
it's a nice-to-have.

The first mini-patch moves the update of bio_iovec(bio)->bv_offset and
->bv_len after the call of bi_end_io where bi_idx gets updated so they get
updated together.  Ok with Jens.

The second part of the patch modifies the multwrite hack in PIO non-
taskfile ide disk code.  It modifies the bi_idx field to walk the bios and
doesn't reset it correctly before ending the request.  The patch uses the
segment counter in the request field to correctly restore the bi_idx field
before ending the request.  Can't possibly break anything since it's
working on the local request copy ("scratchpad") anyway.  Also does this in
legacy/pdc4030.c (similar code).  The code modified here is going to die
anyway any trying to fix it would be too invasive.  Ok with Bartlomiej.
parent 9c02379c
......@@ -2488,8 +2488,6 @@ static int __end_that_request_first(struct request *req, int uptodate,
* not a complete bvec done
*/
if (unlikely(nbytes > nr_bytes)) {
bio_iovec_idx(bio, idx)->bv_offset += nr_bytes;
bio_iovec_idx(bio, idx)->bv_len -= nr_bytes;
bio_nbytes += nr_bytes;
total_bytes += nr_bytes;
break;
......@@ -2525,7 +2523,9 @@ static int __end_that_request_first(struct request *req, int uptodate,
*/
if (bio_nbytes) {
bio_endio(bio, bio_nbytes, error);
req->bio->bi_idx += next_idx;
bio->bi_idx += next_idx;
bio_iovec(bio)->bv_offset += nr_bytes;
bio_iovec(bio)->bv_len -= nr_bytes;
}
blk_recalc_rq_sectors(req, total_bytes >> 9);
......
......@@ -277,7 +277,7 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount)
* all bvecs in this one.
*/
if (++bio->bi_idx >= bio->bi_vcnt) {
bio->bi_idx = 0;
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
bio = bio->bi_next;
}
......@@ -286,7 +286,8 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount)
mcount = 0;
} else {
rq->bio = bio;
rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
rq->nr_cbio_segments = bio_segments(bio);
rq->current_nr_sectors = bio_cur_sectors(bio);
rq->hard_cur_sectors = rq->current_nr_sectors;
}
}
......@@ -308,6 +309,7 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
struct request *rq = &hwgroup->wrq;
struct bio *bio = rq->bio;
u8 stat;
stat = hwif->INB(IDE_STATUS_REG);
......@@ -328,14 +330,17 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
* we can end the original request.
*/
if (!rq->nr_sectors) { /* all done? */
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
rq = hwgroup->rq;
ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped;
}
}
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
/* the original code did this here (?) */
return ide_stopped;
}
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
return DRIVER(drive)->error(drive, "multwrite_intr", stat);
}
......
......@@ -443,7 +443,12 @@ static ide_startstop_t promise_read_intr (ide_drive_t *drive)
static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
#ifdef CONFIG_IDE_TASKFILE_IO
struct request *rq = hwgroup->rq;
#else
struct request *rq = &hwgroup->wrq;
struct bio *bio = rq->bio;
#endif
if ((HWIF(drive)->INB(IDE_STATUS_REG)) & BUSY_STAT) {
if (time_before(jiffies, hwgroup->poll_timeout)) {
......@@ -472,6 +477,8 @@ static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
while (rq->bio != rq->cbio)
(void) DRIVER(drive)->end_request(drive, 1, bio_sectors(rq->bio));
#else
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
rq = hwgroup->rq;
DRIVER(drive)->end_request(drive, 1, rq->hard_nr_sectors);
#endif
return ide_stopped;
......@@ -530,7 +537,7 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount)
* all bvecs in this one.
*/
if (++bio->bi_idx >= bio->bi_vcnt) {
bio->bi_idx = 0;
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
bio = bio->bi_next;
}
......@@ -539,7 +546,8 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount)
mcount = 0;
} else {
rq->bio = bio;
rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
rq->nr_cbio_segments = bio_segments(bio);
rq->current_nr_sectors = bio_cur_sectors(bio);
rq->hard_cur_sectors = rq->current_nr_sectors;
}
}
......@@ -561,6 +569,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
ide_hwgroup_t *hwgroup = HWGROUP(drive);
#ifdef CONFIG_IDE_TASKFILE_IO
struct request *rq = hwgroup->rq;
#else
struct request *rq = &hwgroup->wrq;
struct bio *bio = rq->bio;
#endif
if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) {
......@@ -575,6 +586,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
}
hwgroup->poll_timeout = 0;
printk(KERN_ERR "%s: write timed-out!\n",drive->name);
#ifndef CONFIG_IDE_TASKFILE_IO
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
#endif
return DRIVER(drive)->error(drive, "write timeout",
HWIF(drive)->INB(IDE_STATUS_REG));
}
......
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