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
This commit is contained in:
parent
0e53f607e9
commit
aa9ab5296b
@ -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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user