mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Fix returning incorrect bio_resid value with failed BIO_DELETE requests.
Neither residual length reported for ATA/SCSI command nor one from another BIO_DELETE request are in any way related to the value to be returned.
This commit is contained in:
parent
9fcd8e9ebd
commit
7651b989e8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=253752
@ -1684,6 +1684,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
struct ccb_ataio *ataio;
|
||||
struct ccb_getdev *cgd;
|
||||
struct cam_path *path;
|
||||
int state;
|
||||
|
||||
softc = (struct ada_softc *)periph->softc;
|
||||
ataio = &done_ccb->ataio;
|
||||
@ -1691,31 +1692,20 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
|
||||
CAM_DEBUG(path, CAM_DEBUG_TRACE, ("adadone\n"));
|
||||
|
||||
switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
|
||||
state = ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK;
|
||||
switch (state) {
|
||||
case ADA_CCB_BUFFER_IO:
|
||||
case ADA_CCB_TRIM:
|
||||
{
|
||||
struct bio *bp;
|
||||
int error;
|
||||
|
||||
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
|
||||
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||
int error;
|
||||
|
||||
error = adaerror(done_ccb, 0, 0);
|
||||
if (error == ERESTART) {
|
||||
/* A retry was scheduled, so just return. */
|
||||
return;
|
||||
}
|
||||
if (error != 0) {
|
||||
bp->bio_error = error;
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
} else {
|
||||
bp->bio_resid = ataio->resid;
|
||||
bp->bio_error = 0;
|
||||
if (bp->bio_resid != 0)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
}
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
cam_release_devq(path,
|
||||
/*relsim_flags*/0,
|
||||
@ -1725,26 +1715,38 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
} else {
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
panic("REQ_CMP with QFRZN");
|
||||
bp->bio_resid = ataio->resid;
|
||||
if (ataio->resid > 0)
|
||||
error = 0;
|
||||
}
|
||||
bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
|
||||
bp->bio_error = error;
|
||||
if (error != 0) {
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
} else {
|
||||
if (state == ADA_CCB_TRIM)
|
||||
bp->bio_resid = 0;
|
||||
else
|
||||
bp->bio_resid = ataio->resid;
|
||||
if (bp->bio_resid > 0)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
}
|
||||
softc->outstanding_cmds--;
|
||||
if (softc->outstanding_cmds == 0)
|
||||
softc->flags |= ADA_FLAG_WENT_IDLE;
|
||||
if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) ==
|
||||
ADA_CCB_TRIM) {
|
||||
if (state == ADA_CCB_TRIM) {
|
||||
struct trim_request *req =
|
||||
(struct trim_request *)ataio->data_ptr;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) {
|
||||
struct bio *bp1 = req->bps[i];
|
||||
|
||||
bp1->bio_resid = bp->bio_resid;
|
||||
|
||||
bp1->bio_error = bp->bio_error;
|
||||
if (bp->bio_flags & BIO_ERROR)
|
||||
if (bp->bio_flags & BIO_ERROR) {
|
||||
bp1->bio_flags |= BIO_ERROR;
|
||||
bp1->bio_resid = bp1->bio_bcount;
|
||||
} else
|
||||
bp1->bio_resid = 0;
|
||||
biodone(bp1);
|
||||
}
|
||||
softc->trim_running = 0;
|
||||
|
@ -2921,7 +2921,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
}
|
||||
} else if (bp != NULL) {
|
||||
bp->bio_resid = csio->resid;
|
||||
if (state == DA_CCB_DELETE)
|
||||
bp->bio_resid = 0;
|
||||
else
|
||||
bp->bio_resid = csio->resid;
|
||||
bp->bio_error = 0;
|
||||
if (bp->bio_resid != 0)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
@ -2935,7 +2938,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
} else if (bp != NULL) {
|
||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||
panic("REQ_CMP with QFRZN");
|
||||
bp->bio_resid = csio->resid;
|
||||
if (state == DA_CCB_DELETE)
|
||||
bp->bio_resid = 0;
|
||||
else
|
||||
bp->bio_resid = csio->resid;
|
||||
if (csio->resid > 0)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
if (softc->error_inject != 0) {
|
||||
@ -2944,7 +2950,6 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
softc->error_inject = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2959,10 +2964,12 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
if (state == DA_CCB_DELETE) {
|
||||
while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
|
||||
!= NULL) {
|
||||
bp1->bio_resid = bp->bio_resid;
|
||||
bp1->bio_error = bp->bio_error;
|
||||
if (bp->bio_flags & BIO_ERROR)
|
||||
if (bp->bio_flags & BIO_ERROR) {
|
||||
bp1->bio_flags |= BIO_ERROR;
|
||||
bp1->bio_resid = bp1->bio_bcount;
|
||||
} else
|
||||
bp1->bio_resid = 0;
|
||||
biodone(bp1);
|
||||
}
|
||||
softc->delete_running = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user