svn commit: r253752 - in head/sys/cam: ata scsi
Alexander Motin
mav at FreeBSD.org
Sun Jul 28 19:56:09 UTC 2013
Author: mav
Date: Sun Jul 28 19:56:08 2013
New Revision: 253752
URL: http://svnweb.freebsd.org/changeset/base/253752
Log:
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.
Modified:
head/sys/cam/ata/ata_da.c
head/sys/cam/scsi/scsi_da.c
Modified: head/sys/cam/ata/ata_da.c
==============================================================================
--- head/sys/cam/ata/ata_da.c Sun Jul 28 19:49:39 2013 (r253751)
+++ head/sys/cam/ata/ata_da.c Sun Jul 28 19:56:08 2013 (r253752)
@@ -1684,6 +1684,7 @@ adadone(struct cam_periph *periph, union
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
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
} 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;
Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c Sun Jul 28 19:49:39 2013 (r253751)
+++ head/sys/cam/scsi/scsi_da.c Sun Jul 28 19:56:08 2013 (r253752)
@@ -2921,7 +2921,10 @@ dadone(struct cam_periph *periph, union
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
} 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
bp->bio_flags |= BIO_ERROR;
softc->error_inject = 0;
}
-
}
/*
@@ -2959,10 +2964,12 @@ dadone(struct cam_periph *periph, union
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;
More information about the svn-src-head
mailing list