summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>2001-05-22 02:31:08 +0000
committergrog <grog@FreeBSD.org>2001-05-22 02:31:08 +0000
commitaa9ab5296b71394518487f31cde37fa4e0702ce6 (patch)
tree016f0094b254b41c3d4f9cefa635b3fd6bfbdc24 /sys/dev
parent0e53f607e9ec4a2cfddabc6ebb5c3cda7338ae62 (diff)
downloadFreeBSD-src-aa9ab5296b71394518487f31cde37fa4e0702ce6.zip
FreeBSD-src-aa9ab5296b71394518487f31cde37fa4e0702ce6.tar.gz
complete_rqe:
In case of error, check the VF_RETRYERRORS flag in the subdisk and don't take the subdisk down if it's set, just retry the I/O. Requested by: peter If the buffer has been copied (XFR_COPYBUF), release the copied buffer when the I/O completes. Suggested by: alfred
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/vinum/vinuminterrupt.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/sys/dev/vinum/vinuminterrupt.c b/sys/dev/vinum/vinuminterrupt.c
index d5ce417..461c06b 100644
--- a/sys/dev/vinum/vinuminterrupt.c
+++ b/sys/dev/vinum/vinuminterrupt.c
@@ -39,7 +39,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
- * $Id: vinuminterrupt.c,v 1.9 2000/02/16 01:59:02 grog Exp grog $
+ * $Id: vinuminterrupt.c,v 1.12 2000/11/24 03:41:42 grog Exp grog $
* $FreeBSD$
*/
@@ -67,6 +67,8 @@ complete_rqe(struct buf *bp)
struct rqgroup *rqg;
struct buf *ubp; /* user buffer */
struct drive *drive;
+ struct sd *sd;
+ char *gravity; /* for error messages */
rqe = (struct rqelement *) bp; /* point to the element element that completed */
rqg = rqe->rqg; /* and the request group */
@@ -84,20 +86,48 @@ complete_rqe(struct buf *bp)
||(vinum_conf.active == VINUM_MAXACTIVE)) /* or the global limit */
wakeup(&launch_requests); /* let another one at it */
if ((bp->b_io.bio_flags & BIO_ERROR) != 0) { /* transfer in error */
+ gravity = "";
+ sd = &SD[rqe->sdno];
+
if (bp->b_error != 0) /* did it return a number? */
rq->error = bp->b_error; /* yes, put it in. */
else if (rq->error == 0) /* no: do we have one already? */
rq->error = EIO; /* no: catchall "I/O error" */
- SD[rqe->sdno].lasterror = rq->error;
+ sd->lasterror = rq->error;
if (bp->b_iocmd == BIO_READ) { /* read operation */
- log(LOG_ERR, "%s: fatal read I/O error\n", SD[rqe->sdno].name);
- set_sd_state(rqe->sdno, sd_crashed, setstate_force); /* subdisk is crashed */
+ if ((rq->error == ENXIO) || (sd->flags & VF_RETRYERRORS) == 0) {
+ gravity = " fatal";
+ set_sd_state(rqe->sdno, sd_crashed, setstate_force); /* subdisk is crashed */
+ }
+ log(LOG_ERR,
+ "%s:%s read error, block %d for %ld bytes\n",
+ gravity,
+ sd->name,
+ bp->b_blkno,
+ bp->b_bcount);
} else { /* write operation */
- log(LOG_ERR, "%s: fatal write I/O error\n", SD[rqe->sdno].name);
- set_sd_state(rqe->sdno, sd_stale, setstate_force); /* subdisk is stale */
+ if ((rq->error == ENXIO) || (sd->flags & VF_RETRYERRORS) == 0) {
+ gravity = "fatal ";
+ set_sd_state(rqe->sdno, sd_stale, setstate_force); /* subdisk is stale */
+ }
+ log(LOG_ERR,
+ "%s:%s write error, block %d for %ld bytes\n",
+ gravity,
+ sd->name,
+ bp->b_blkno,
+ bp->b_bcount);
}
+ log(LOG_ERR,
+ "%s: user buffer block %d for %ld bytes\n",
+ sd->name,
+ ubp->b_blkno,
+ ubp->b_bcount);
if (rq->error == ENXIO) { /* the drive's down too */
- log(LOG_ERR, "%s: fatal drive I/O error\n", DRIVE[rqe->driveno].label.name);
+ log(LOG_ERR,
+ "%s: fatal drive I/O error, block %d for %ld bytes\n",
+ DRIVE[rqe->driveno].label.name,
+ bp->b_blkno,
+ bp->b_bcount);
DRIVE[rqe->driveno].lasterror = rq->error;
set_drive_state(rqe->driveno, /* take the drive down */
drive_down,
@@ -192,6 +222,10 @@ complete_rqe(struct buf *bp)
ubp->b_resid = 0; /* completed our transfer */
if (rq->isplex == 0) /* volume request, */
VOL[rq->volplex.volno].active--; /* another request finished */
+ if (rq->flags & XFR_COPYBUF) {
+ Free(ubp->b_data);
+ ubp->b_data = rq->save_data;
+ }
bufdone(ubp); /* top level buffer completed */
freerq(rq); /* return the request storage */
}
OpenPOWER on IntegriCloud