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, ...@@ -2488,8 +2488,6 @@ static int __end_that_request_first(struct request *req, int uptodate,
* not a complete bvec done * not a complete bvec done
*/ */
if (unlikely(nbytes > nr_bytes)) { 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; bio_nbytes += nr_bytes;
total_bytes += nr_bytes; total_bytes += nr_bytes;
break; break;
...@@ -2525,7 +2523,9 @@ static int __end_that_request_first(struct request *req, int uptodate, ...@@ -2525,7 +2523,9 @@ static int __end_that_request_first(struct request *req, int uptodate,
*/ */
if (bio_nbytes) { if (bio_nbytes) {
bio_endio(bio, bio_nbytes, error); 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); blk_recalc_rq_sectors(req, total_bytes >> 9);
......
...@@ -277,7 +277,7 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount) ...@@ -277,7 +277,7 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount)
* all bvecs in this one. * all bvecs in this one.
*/ */
if (++bio->bi_idx >= bio->bi_vcnt) { 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; bio = bio->bi_next;
} }
...@@ -286,7 +286,8 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount) ...@@ -286,7 +286,8 @@ static void ide_multwrite(ide_drive_t *drive, unsigned int mcount)
mcount = 0; mcount = 0;
} else { } else {
rq->bio = bio; 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; rq->hard_cur_sectors = rq->current_nr_sectors;
} }
} }
...@@ -308,6 +309,7 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) ...@@ -308,6 +309,7 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct request *rq = &hwgroup->wrq; struct request *rq = &hwgroup->wrq;
struct bio *bio = rq->bio;
u8 stat; u8 stat;
stat = hwif->INB(IDE_STATUS_REG); stat = hwif->INB(IDE_STATUS_REG);
...@@ -328,14 +330,17 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) ...@@ -328,14 +330,17 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
* we can end the original request. * we can end the original request.
*/ */
if (!rq->nr_sectors) { /* all done? */ if (!rq->nr_sectors) { /* all done? */
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
rq = hwgroup->rq; rq = hwgroup->rq;
ide_end_request(drive, 1, rq->nr_sectors); ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
} }
} }
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
/* the original code did this here (?) */ /* the original code did this here (?) */
return ide_stopped; return ide_stopped;
} }
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
return DRIVER(drive)->error(drive, "multwrite_intr", stat); return DRIVER(drive)->error(drive, "multwrite_intr", stat);
} }
......
...@@ -443,7 +443,12 @@ static ide_startstop_t promise_read_intr (ide_drive_t *drive) ...@@ -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) static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
{ {
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
#ifdef CONFIG_IDE_TASKFILE_IO
struct request *rq = hwgroup->rq; 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 ((HWIF(drive)->INB(IDE_STATUS_REG)) & BUSY_STAT) {
if (time_before(jiffies, hwgroup->poll_timeout)) { if (time_before(jiffies, hwgroup->poll_timeout)) {
...@@ -472,6 +477,8 @@ static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive) ...@@ -472,6 +477,8 @@ static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive)
while (rq->bio != rq->cbio) while (rq->bio != rq->cbio)
(void) DRIVER(drive)->end_request(drive, 1, bio_sectors(rq->bio)); (void) DRIVER(drive)->end_request(drive, 1, bio_sectors(rq->bio));
#else #else
bio->bi_idx = bio->bi_vcnt - rq->nr_cbio_segments;
rq = hwgroup->rq;
DRIVER(drive)->end_request(drive, 1, rq->hard_nr_sectors); DRIVER(drive)->end_request(drive, 1, rq->hard_nr_sectors);
#endif #endif
return ide_stopped; return ide_stopped;
...@@ -530,7 +537,7 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount) ...@@ -530,7 +537,7 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount)
* all bvecs in this one. * all bvecs in this one.
*/ */
if (++bio->bi_idx >= bio->bi_vcnt) { 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; bio = bio->bi_next;
} }
...@@ -539,7 +546,8 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount) ...@@ -539,7 +546,8 @@ static void promise_multwrite (ide_drive_t *drive, unsigned int mcount)
mcount = 0; mcount = 0;
} else { } else {
rq->bio = bio; 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; rq->hard_cur_sectors = rq->current_nr_sectors;
} }
} }
...@@ -561,6 +569,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) ...@@ -561,6 +569,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
#ifdef CONFIG_IDE_TASKFILE_IO #ifdef CONFIG_IDE_TASKFILE_IO
struct request *rq = hwgroup->rq; struct request *rq = hwgroup->rq;
#else
struct request *rq = &hwgroup->wrq;
struct bio *bio = rq->bio;
#endif #endif
if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) { if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) {
...@@ -575,6 +586,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) ...@@ -575,6 +586,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
} }
hwgroup->poll_timeout = 0; hwgroup->poll_timeout = 0;
printk(KERN_ERR "%s: write timed-out!\n",drive->name); 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", return DRIVER(drive)->error(drive, "write timeout",
HWIF(drive)->INB(IDE_STATUS_REG)); 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