diff options
Diffstat (limited to 'sys/cam/ctl/ctl.c')
-rw-r--r-- | sys/cam/ctl/ctl.c | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 38dfa80..5b804b1 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -5310,12 +5310,14 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) int length, longid, thirdparty_id, resv_id; struct ctl_softc *ctl_softc; struct ctl_lun *lun; + uint32_t residx; length = 0; resv_id = 0; CTL_DEBUG_PRINT(("ctl_scsi_release\n")); + residx = ctl_get_resindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; ctl_softc = control_softc; @@ -5373,14 +5375,8 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) * released, though, by the initiator who made it or by one of * several reset type events. */ - if (lun->flags & CTL_LUN_RESERVED) { - if ((ctsio->io_hdr.nexus.initid.id == lun->rsv_nexus.initid.id) - && (ctsio->io_hdr.nexus.targ_port == lun->rsv_nexus.targ_port) - && (ctsio->io_hdr.nexus.targ_target.id == - lun->rsv_nexus.targ_target.id)) { + if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == residx)) lun->flags &= ~CTL_LUN_RESERVED; - } - } mtx_unlock(&lun->lun_lock); @@ -5404,6 +5400,7 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) uint64_t thirdparty_id; struct ctl_softc *ctl_softc; struct ctl_lun *lun; + uint32_t residx; extent = 0; thirdparty = 0; @@ -5414,6 +5411,7 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_reserve\n")); + residx = ctl_get_resindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; ctl_softc = control_softc; @@ -5462,19 +5460,14 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) thirdparty_id = scsi_8btou64(ctsio->kern_data_ptr); mtx_lock(&lun->lun_lock); - if (lun->flags & CTL_LUN_RESERVED) { - if ((ctsio->io_hdr.nexus.initid.id != lun->rsv_nexus.initid.id) - || (ctsio->io_hdr.nexus.targ_port != lun->rsv_nexus.targ_port) - || (ctsio->io_hdr.nexus.targ_target.id != - lun->rsv_nexus.targ_target.id)) { - ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; - ctsio->io_hdr.status = CTL_SCSI_ERROR; - goto bailout; - } + if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx != residx)) { + ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; + ctsio->io_hdr.status = CTL_SCSI_ERROR; + goto bailout; } lun->flags |= CTL_LUN_RESERVED; - lun->rsv_nexus = ctsio->io_hdr.nexus; + lun->res_idx = residx; ctsio->scsi_status = SCSI_STATUS_OK; ctsio->io_hdr.status = CTL_SUCCESS; @@ -11273,6 +11266,7 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio) { int retval; + uint32_t residx; retval = 0; @@ -11297,12 +11291,10 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, * even on reserved LUNs, and if this initiator isn't the one who * reserved us, reject the command with a reservation conflict. */ + residx = ctl_get_resindex(&ctsio->io_hdr.nexus); if ((lun->flags & CTL_LUN_RESERVED) && ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_RESV) == 0)) { - if ((ctsio->io_hdr.nexus.initid.id != lun->rsv_nexus.initid.id) - || (ctsio->io_hdr.nexus.targ_port != lun->rsv_nexus.targ_port) - || (ctsio->io_hdr.nexus.targ_target.id != - lun->rsv_nexus.targ_target.id)) { + if (lun->res_idx != residx) { ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; ctsio->io_hdr.status = CTL_SCSI_ERROR; retval = 1; @@ -11310,11 +11302,8 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, } } - if ( (lun->flags & CTL_LUN_PR_RESERVED) + if ((lun->flags & CTL_LUN_PR_RESERVED) && ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV) == 0)) { - uint32_t residx; - - residx = ctl_get_resindex(&ctsio->io_hdr.nexus); /* * if we aren't registered or it's a res holder type * reservation and this isn't the res holder then set a @@ -12178,9 +12167,10 @@ ctl_i_t_nexus_reset(union ctl_io *io) { struct ctl_softc *softc = control_softc; struct ctl_lun *lun; - uint32_t initindex; + uint32_t initindex, residx; initindex = ctl_get_initindex(&io->io_hdr.nexus); + residx = ctl_get_resindex(&io->io_hdr.nexus); mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(lun, &softc->lun_list, links) { mtx_lock(&lun->lun_lock); @@ -12190,6 +12180,8 @@ ctl_i_t_nexus_reset(union ctl_io *io) #ifdef CTL_WITH_CA ctl_clear_mask(lun->have_ca, initindex); #endif + if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == residx)) + lun->flags &= ~CTL_LUN_RESERVED; lun->pending_ua[initindex] |= CTL_UA_I_T_NEXUS_LOSS; mtx_unlock(&lun->lun_lock); } |