diff options
author | phk <phk@FreeBSD.org> | 2003-04-14 08:49:54 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-04-14 08:49:54 +0000 |
commit | c10cd4d964cdb50012421cb5d82c7e1ac7357fcf (patch) | |
tree | c87ecfa8ba65a2d2726125e109c8484f8719f077 /sys/dev | |
parent | da1c42b4c0ecd653522d657a51eec4ef70210524 (diff) | |
download | FreeBSD-src-c10cd4d964cdb50012421cb5d82c7e1ac7357fcf.zip FreeBSD-src-c10cd4d964cdb50012421cb5d82c7e1ac7357fcf.tar.gz |
More correct patch: Only call biofinish if we have not already sent
any children down the mesh.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ccd/ccd.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/dev/ccd/ccd.c b/sys/dev/ccd/ccd.c index 7dd43f9..9af6b4a 100644 --- a/sys/dev/ccd/ccd.c +++ b/sys/dev/ccd/ccd.c @@ -564,6 +564,7 @@ ccdstart(struct ccd_s *cs, struct bio *bp) caddr_t addr; daddr_t bn; int err; + int sent; /* * Translate the partition-relative block number to an absolute. @@ -574,11 +575,24 @@ ccdstart(struct ccd_s *cs, struct bio *bp) * Allocate component buffers and fire off the requests */ addr = bp->bio_data; + sent = 0; for (bcount = bp->bio_bcount; bcount > 0; bcount -= rcount) { err = ccdbuffer(cbp, cs, bp, bn, addr, bcount); if (err) { printf("ccdbuffer error %d\n", err); - biofinish(bp, NULL, err); + if (!sent) + biofinish(bp, NULL, err); + else { + /* + * XXX: maybe a race where the partners + * XXX: we sent already have been in + * XXX: ccdiodone(). Single-threaded g_down + * XXX: may protect against this. + */ + bp->bio_resid -= bcount; + bp->bio_error = err; + bp->bio_flags |= BIO_ERROR; + } return; } rcount = cbp[0]->cb_buf.bio_bcount; @@ -596,6 +610,7 @@ ccdstart(struct ccd_s *cs, struct bio *bp) if (cbp[0]->cb_buf.bio_cmd == BIO_WRITE) { BIO_STRATEGY(&cbp[0]->cb_buf); BIO_STRATEGY(&cbp[1]->cb_buf); + sent++; } else { int pick = cs->sc_pick; daddr_t range = cs->sc_size / 16; @@ -607,12 +622,14 @@ ccdstart(struct ccd_s *cs, struct bio *bp) } cs->sc_blk[pick] = bn + btodb(rcount); BIO_STRATEGY(&cbp[pick]->cb_buf); + sent++; } } else { /* * Not mirroring */ BIO_STRATEGY(&cbp[0]->cb_buf); + sent++; } bn += btodb(rcount); addr += rcount; |