Author: trasz Date: Wed Oct 9 20:09:58 2013 New Revision: 256238 URL: http://svnweb.freebsd.org/changeset/base/256238
Log: Properly handle residual count in Data-In PDUs with S bit set. Approved by: re (gjb) Sponsored by: FreeBSD Foundation Modified: head/sys/dev/iscsi/iscsi.c Modified: head/sys/dev/iscsi/iscsi.c ============================================================================== --- head/sys/dev/iscsi/iscsi.c Wed Oct 9 20:00:04 2013 (r256237) +++ head/sys/dev/iscsi/iscsi.c Wed Oct 9 20:09:58 2013 (r256238) @@ -966,22 +966,43 @@ iscsi_pdu_handle_data_in(struct icl_pdu * XXX: Check DataSN. * XXX: Check F. */ - if (bhsdi->bhsdi_flags & BHSDI_FLAGS_S) { - //ISCSI_SESSION_DEBUG(is, "got S flag; status 0x%x", bhsdi->bhsdi_status); - if (bhsdi->bhsdi_status == 0) { - io->io_ccb->ccb_h.status = CAM_REQ_CMP; - } else { - if ((io->io_ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { - xpt_freeze_devq(io->io_ccb->ccb_h.path, 1); - ISCSI_SESSION_DEBUG(is, "freezing devq"); + if ((bhsdi->bhsdi_flags & BHSDI_FLAGS_S) == 0) { + /* + * Nothing more to do. + */ + icl_pdu_free(response); + return; + } + + //ISCSI_SESSION_DEBUG(is, "got S flag; status 0x%x", bhsdi->bhsdi_status); + if (bhsdi->bhsdi_status == 0) { + io->io_ccb->ccb_h.status = CAM_REQ_CMP; + } else { + if ((io->io_ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { + xpt_freeze_devq(io->io_ccb->ccb_h.path, 1); + ISCSI_SESSION_DEBUG(is, "freezing devq"); + } + io->io_ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_DEV_QFRZN; + csio->scsi_status = bhsdi->bhsdi_status; + } + + if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { + KASSERT(io->io_received <= csio->dxfer_len, + ("io->io_received > csio->dxfer_len")); + if (io->io_received < csio->dxfer_len) { + csio->resid = ntohl(bhsdi->bhsdi_residual_count); + if (csio->resid != csio->dxfer_len - io->io_received) { + ISCSI_SESSION_WARN(is, "underflow mismatch: " + "target indicates %d, we calculated %zd", + csio->resid, + csio->dxfer_len - io->io_received); } - io->io_ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_DEV_QFRZN; - csio->scsi_status = bhsdi->bhsdi_status; + csio->resid = csio->dxfer_len - io->io_received; } - xpt_done(io->io_ccb); - iscsi_outstanding_remove(is, io); } + xpt_done(io->io_ccb); + iscsi_outstanding_remove(is, io); icl_pdu_free(response); } _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"