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_ataio *ataio;
|
||||||
struct ccb_getdev *cgd;
|
struct ccb_getdev *cgd;
|
||||||
struct cam_path *path;
|
struct cam_path *path;
|
||||||
|
int state;
|
||||||
|
|
||||||
softc = (struct ada_softc *)periph->softc;
|
softc = (struct ada_softc *)periph->softc;
|
||||||
ataio = &done_ccb->ataio;
|
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"));
|
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_BUFFER_IO:
|
||||||
case ADA_CCB_TRIM:
|
case ADA_CCB_TRIM:
|
||||||
{
|
{
|
||||||
struct bio *bp;
|
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) {
|
if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
int error;
|
|
||||||
|
|
||||||
error = adaerror(done_ccb, 0, 0);
|
error = adaerror(done_ccb, 0, 0);
|
||||||
if (error == ERESTART) {
|
if (error == ERESTART) {
|
||||||
/* A retry was scheduled, so just return. */
|
/* A retry was scheduled, so just return. */
|
||||||
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)
|
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||||
cam_release_devq(path,
|
cam_release_devq(path,
|
||||||
/*relsim_flags*/0,
|
/*relsim_flags*/0,
|
||||||
@ -1725,26 +1715,38 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
} else {
|
} else {
|
||||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||||
panic("REQ_CMP with QFRZN");
|
panic("REQ_CMP with QFRZN");
|
||||||
bp->bio_resid = ataio->resid;
|
error = 0;
|
||||||
if (ataio->resid > 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;
|
bp->bio_flags |= BIO_ERROR;
|
||||||
}
|
}
|
||||||
softc->outstanding_cmds--;
|
softc->outstanding_cmds--;
|
||||||
if (softc->outstanding_cmds == 0)
|
if (softc->outstanding_cmds == 0)
|
||||||
softc->flags |= ADA_FLAG_WENT_IDLE;
|
softc->flags |= ADA_FLAG_WENT_IDLE;
|
||||||
if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) ==
|
if (state == ADA_CCB_TRIM) {
|
||||||
ADA_CCB_TRIM) {
|
|
||||||
struct trim_request *req =
|
struct trim_request *req =
|
||||||
(struct trim_request *)ataio->data_ptr;
|
(struct trim_request *)ataio->data_ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) {
|
for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) {
|
||||||
struct bio *bp1 = req->bps[i];
|
struct bio *bp1 = req->bps[i];
|
||||||
|
|
||||||
bp1->bio_resid = bp->bio_resid;
|
|
||||||
bp1->bio_error = bp->bio_error;
|
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_flags |= BIO_ERROR;
|
||||||
|
bp1->bio_resid = bp1->bio_bcount;
|
||||||
|
} else
|
||||||
|
bp1->bio_resid = 0;
|
||||||
biodone(bp1);
|
biodone(bp1);
|
||||||
}
|
}
|
||||||
softc->trim_running = 0;
|
softc->trim_running = 0;
|
||||||
|
@ -2921,7 +2921,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
bp->bio_flags |= BIO_ERROR;
|
bp->bio_flags |= BIO_ERROR;
|
||||||
}
|
}
|
||||||
} else if (bp != NULL) {
|
} 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;
|
bp->bio_error = 0;
|
||||||
if (bp->bio_resid != 0)
|
if (bp->bio_resid != 0)
|
||||||
bp->bio_flags |= BIO_ERROR;
|
bp->bio_flags |= BIO_ERROR;
|
||||||
@ -2935,7 +2938,10 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
} else if (bp != NULL) {
|
} else if (bp != NULL) {
|
||||||
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
|
||||||
panic("REQ_CMP with QFRZN");
|
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)
|
if (csio->resid > 0)
|
||||||
bp->bio_flags |= BIO_ERROR;
|
bp->bio_flags |= BIO_ERROR;
|
||||||
if (softc->error_inject != 0) {
|
if (softc->error_inject != 0) {
|
||||||
@ -2944,7 +2950,6 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
bp->bio_flags |= BIO_ERROR;
|
bp->bio_flags |= BIO_ERROR;
|
||||||
softc->error_inject = 0;
|
softc->error_inject = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2959,10 +2964,12 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
if (state == DA_CCB_DELETE) {
|
if (state == DA_CCB_DELETE) {
|
||||||
while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
|
while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
bp1->bio_resid = bp->bio_resid;
|
|
||||||
bp1->bio_error = bp->bio_error;
|
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_flags |= BIO_ERROR;
|
||||||
|
bp1->bio_resid = bp1->bio_bcount;
|
||||||
|
} else
|
||||||
|
bp1->bio_resid = 0;
|
||||||
biodone(bp1);
|
biodone(bp1);
|
||||||
}
|
}
|
||||||
softc->delete_running = 0;
|
softc->delete_running = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user