diff options
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/ctl/ctl.c | 205 | ||||
-rw-r--r-- | sys/cam/ctl/ctl_private.h | 7 |
2 files changed, 61 insertions, 151 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 4ed6a5a..7edf582 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -2990,12 +2990,11 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, for (j = 0; j < (CTL_MAX_PORTS * 2); j++) { for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ idx = j * CTL_MAX_INIT_PER_PORT + k; - if (lun->per_res[idx].registered == 0) + if (lun->pr_keys[idx] == 0) continue; printf(" LUN %d port %d iid %d key " "%#jx\n", i, j, k, - (uintmax_t)scsi_8btou64( - lun->per_res[idx].res_key.key)); + (uintmax_t)lun->pr_keys[idx]); } } } @@ -5536,7 +5535,7 @@ ctl_start_stop(struct ctl_scsiio *ctsio) uint32_t residx; residx = ctl_get_resindex(&ctsio->io_hdr.nexus); - if (!lun->per_res[residx].registered + if (lun->pr_keys[residx] == 0 || (lun->pr_res_idx!=residx && lun->res_type < 4)) { ctl_set_reservation_conflict(ctsio); @@ -5827,7 +5826,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio) && residx != lun->pr_res_idx) || ((lun->res_type == SPR_TYPE_EX_AC_RO || lun->res_type == SPR_TYPE_EX_AC_AR) - && !lun->per_res[residx].registered)) { + && lun->pr_keys[residx] == 0)) { ctl_set_reservation_conflict(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -6882,7 +6881,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) && residx != lun->pr_res_idx) || ((lun->res_type == SPR_TYPE_EX_AC_RO || lun->res_type == SPR_TYPE_EX_AC_AR) - && !lun->per_res[residx].registered)) { + && lun->pr_keys[residx] == 0)) { ctl_set_reservation_conflict(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -7825,7 +7824,7 @@ retry: lun->pr_key_count, res_keys->header.length); for (i = 0, key_count = 0; i < 2*CTL_MAX_INITIATORS; i++) { - if (!lun->per_res[i].registered) + if (lun->pr_keys[i] == 0) continue; /* @@ -7851,10 +7850,8 @@ retry: key_count++; continue; } - memcpy(res_keys->keys[key_count].key, - lun->per_res[i].res_key.key, - ctl_min(sizeof(res_keys->keys[key_count].key), - sizeof(lun->per_res[i].res_key))); + scsi_u64to8b(lun->pr_keys[i], + res_keys->keys[key_count].key); key_count++; } break; @@ -7905,9 +7902,8 @@ retry: * is 0, since it doesn't really matter. */ if (lun->pr_res_idx != CTL_PR_ALL_REGISTRANTS) { - memcpy(res->data.reservation, - &lun->per_res[lun->pr_res_idx].res_key, - sizeof(struct scsi_per_res_key)); + scsi_u64to8b(lun->pr_keys[lun->pr_res_idx], + res->data.reservation); } res->data.scopetype = lun->res_type; break; @@ -7958,11 +7954,10 @@ retry: res_desc = &res_status->desc[0]; for (i = 0; i < 2*CTL_MAX_INITIATORS; i++) { - if (!lun->per_res[i].registered) + if (lun->pr_keys[i] == 0) continue; - memcpy(&res_desc->res_key, &lun->per_res[i].res_key.key, - sizeof(res_desc->res_key)); + scsi_u64to8b(lun->pr_keys[i], res_desc->res_key.key); if ((lun->flags & CTL_LUN_PR_RESERVED) && (lun->pr_res_idx == i || lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS)) { @@ -8055,15 +8050,12 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, return (1); } - /* temporarily unregister this nexus */ - lun->per_res[residx].registered = 0; - /* * Unregister everybody else and build UA for * them */ for(i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered == 0) + if (i == residx || lun->pr_keys[i] == 0) continue; if (!persis_offset @@ -8074,11 +8066,8 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, && i >= persis_offset) lun->pending_ua[i-persis_offset] |= CTL_UA_REG_PREEMPT; - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + lun->pr_keys[i] = 0; } - lun->per_res[residx].registered = 1; lun->pr_key_count = 1; lun->res_type = type; if (lun->res_type != SPR_TYPE_WR_EX_AR @@ -8142,16 +8131,11 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, } for (i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered - && memcmp(param->serv_act_res_key, - lun->per_res[i].res_key.key, - sizeof(struct scsi_per_res_key)) != 0) + if (lun->pr_keys[i] != sa_res_key) continue; found = 1; - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + lun->pr_keys[i] = 0; lun->pr_key_count--; if (!persis_offset && i < CTL_MAX_INITIATORS) @@ -8185,9 +8169,7 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, } else { /* Reserved but not all registrants */ /* sa_res_key is res holder */ - if (memcmp(param->serv_act_res_key, - lun->per_res[lun->pr_res_idx].res_key.key, - sizeof(struct scsi_per_res_key)) == 0) { + if (sa_res_key == lun->pr_keys[lun->pr_res_idx]) { /* validate scope and type */ if ((cdb->scope_type & SPR_SCOPE_MASK) != SPR_LU_SCOPE) { @@ -8228,22 +8210,12 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, * except don't unregister the res holder. */ - /* - * Temporarily unregister so it won't get - * removed or UA generated - */ - lun->per_res[residx].registered = 0; for(i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered == 0) + if (i == residx || lun->pr_keys[i] == 0) continue; - if (memcmp(param->serv_act_res_key, - lun->per_res[i].res_key.key, - sizeof(struct scsi_per_res_key)) == 0) { - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, - 0, - sizeof(struct scsi_per_res_key)); + if (sa_res_key == lun->pr_keys[i]) { + lun->pr_keys[i] = 0; lun->pr_key_count--; if (!persis_offset @@ -8268,7 +8240,6 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, CTL_UA_RES_RELEASE; } } - lun->per_res[residx].registered = 1; lun->res_type = type; if (lun->res_type != SPR_TYPE_WR_EX_AR && lun->res_type != SPR_TYPE_EX_AC_AR) @@ -8299,15 +8270,11 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, int found=0; for (i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (memcmp(param->serv_act_res_key, - lun->per_res[i].res_key.key, - sizeof(struct scsi_per_res_key)) != 0) + if (sa_res_key != lun->pr_keys[i]) continue; found = 1; - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + lun->pr_keys[i] = 0; lun->pr_key_count--; if (!persis_offset @@ -8354,26 +8321,22 @@ ctl_pro_preempt(struct ctl_softc *softc, struct ctl_lun *lun, uint64_t res_key, static void ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) { + uint64_t sa_res_key; int i; + sa_res_key = scsi_8btou64(msg->pr.pr_info.sa_res_key); + if (lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS || lun->pr_res_idx == CTL_PR_NO_RESERVATION - || memcmp(&lun->per_res[lun->pr_res_idx].res_key, - msg->pr.pr_info.sa_res_key, - sizeof(struct scsi_per_res_key)) != 0) { - uint64_t sa_res_key; - sa_res_key = scsi_8btou64(msg->pr.pr_info.sa_res_key); - + || sa_res_key != lun->pr_keys[lun->pr_res_idx]) { if (sa_res_key == 0) { - /* temporarily unregister this nexus */ - lun->per_res[msg->pr.pr_info.residx].registered = 0; - /* * Unregister everybody else and build UA for * them */ for(i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered == 0) + if (i == msg->pr.pr_info.residx || + lun->pr_keys[i] == 0) continue; if (!persis_offset @@ -8383,12 +8346,9 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) else if (persis_offset && i >= persis_offset) lun->pending_ua[i - persis_offset] |= CTL_UA_REG_PREEMPT; - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + lun->pr_keys[i] = 0; } - lun->per_res[msg->pr.pr_info.residx].registered = 1; lun->pr_key_count = 1; lun->res_type = msg->pr.pr_info.res_type; if (lun->res_type != SPR_TYPE_WR_EX_AR @@ -8396,14 +8356,10 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) lun->pr_res_idx = msg->pr.pr_info.residx; } else { for (i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (memcmp(msg->pr.pr_info.sa_res_key, - lun->per_res[i].res_key.key, - sizeof(struct scsi_per_res_key)) != 0) + if (sa_res_key == lun->pr_keys[i]) continue; - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + lun->pr_keys[i] = 0; lun->pr_key_count--; if (!persis_offset @@ -8417,21 +8373,13 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) } } } else { - /* - * Temporarily unregister so it won't get removed - * or UA generated - */ - lun->per_res[msg->pr.pr_info.residx].registered = 0; for (i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered == 0) + if (i == msg->pr.pr_info.residx || + lun->pr_keys[i] == 0) continue; - if (memcmp(msg->pr.pr_info.sa_res_key, - lun->per_res[i].res_key.key, - sizeof(struct scsi_per_res_key)) == 0) { - lun->per_res[i].registered = 0; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); + if (sa_res_key == lun->pr_keys[i]) { + lun->pr_keys[i] = 0; lun->pr_key_count--; if (!persis_offset && i < CTL_MAX_INITIATORS) @@ -8454,7 +8402,6 @@ ctl_pro_preempt_other(struct ctl_lun *lun, union ctl_ha_msg *msg) CTL_UA_RES_RELEASE; } } - lun->per_res[msg->pr.pr_info.residx].registered = 1; lun->res_type = msg->pr.pr_info.res_type; if (lun->res_type != SPR_TYPE_WR_EX_AR && lun->res_type != SPR_TYPE_EX_AC_AR) @@ -8552,11 +8499,8 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) */ if ((cdb->action & SPRO_ACTION_MASK) != SPRO_REG_IGNO) { mtx_lock(&lun->lun_lock); - if (lun->per_res[residx].registered) { - if (memcmp(param->res_key.key, - lun->per_res[residx].res_key.key, - ctl_min(sizeof(param->res_key), - sizeof(lun->per_res[residx].res_key))) != 0) { + if (lun->pr_keys[residx] != 0) { + if (res_key != lun->pr_keys[residx]) { /* * The current key passed in doesn't match * the one the initiator previously @@ -8637,14 +8581,12 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) if ((res_key == 0 && (cdb->action & SPRO_ACTION_MASK) == SPRO_REGISTER) || ((cdb->action & SPRO_ACTION_MASK) == SPRO_REG_IGNO - && !lun->per_res[residx].registered)) { + && lun->pr_keys[residx] == 0)) { mtx_unlock(&lun->lun_lock); goto done; } - lun->per_res[residx].registered = 0; - memset(&lun->per_res[residx].res_key, - 0, sizeof(lun->per_res[residx].res_key)); + lun->pr_keys[residx] = 0; lun->pr_key_count--; if (residx == lun->pr_res_idx) { @@ -8663,9 +8605,8 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) */ for (i = 0; i < CTL_MAX_INITIATORS;i++){ - if (lun->per_res[ - i+persis_offset].registered - == 0) + if (lun->pr_keys[ + i + persis_offset] == 0) continue; lun->pending_ua[i] |= CTL_UA_RES_RELEASE; @@ -8695,15 +8636,9 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) * If we aren't registered currently then increment * the key count and set the registered flag. */ - if (!lun->per_res[residx].registered) { + if (lun->pr_keys[residx] == 0) lun->pr_key_count++; - lun->per_res[residx].registered = 1; - } - - memcpy(&lun->per_res[residx].res_key, - param->serv_act_res_key, - ctl_min(sizeof(param->serv_act_res_key), - sizeof(lun->per_res[residx].res_key))); + lun->pr_keys[residx] = sa_res_key; persis_io.hdr.nexus = ctsio->io_hdr.nexus; persis_io.hdr.msg_type = CTL_MSG_PERS_ACTION; @@ -8816,20 +8751,12 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) */ if (type != SPR_TYPE_EX_AC && type != SPR_TYPE_WR_EX) { - /* - * temporarily unregister so we don't generate UA - */ - lun->per_res[residx].registered = 0; - for (i = 0; i < CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i+persis_offset].registered - == 0) + if (i == residx || + lun->pr_keys[i + persis_offset] == 0) continue; - lun->pending_ua[i] |= - CTL_UA_RES_RELEASE; + lun->pending_ua[i] |= CTL_UA_RES_RELEASE; } - - lun->per_res[residx].registered = 1; } mtx_unlock(&lun->lun_lock); /* Send msg to other side */ @@ -8852,13 +8779,10 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) lun->pr_key_count = 0; lun->pr_res_idx = CTL_PR_NO_RESERVATION; - - memset(&lun->per_res[residx].res_key, - 0, sizeof(lun->per_res[residx].res_key)); - lun->per_res[residx].registered = 0; + lun->pr_keys[residx] = 0; for (i=0; i < 2*CTL_MAX_INITIATORS; i++) - if (lun->per_res[i].registered) { + if (lun->pr_keys[i] != 0) { if (!persis_offset && i < CTL_MAX_INITIATORS) lun->pending_ua[i] |= CTL_UA_RES_PREEMPT; @@ -8866,9 +8790,7 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) lun->pending_ua[i-persis_offset] |= CTL_UA_RES_PREEMPT; - memset(&lun->per_res[i].res_key, - 0, sizeof(struct scsi_per_res_key)); - lun->per_res[i].registered = 0; + lun->pr_keys[i] = 0; } lun->PRGeneration++; mtx_unlock(&lun->lun_lock); @@ -8924,20 +8846,15 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) mtx_lock(&lun->lun_lock); switch(msg->pr.pr_info.action) { case CTL_PR_REG_KEY: - if (!lun->per_res[msg->pr.pr_info.residx].registered) { - lun->per_res[msg->pr.pr_info.residx].registered = 1; + if (lun->pr_keys[msg->pr.pr_info.residx] == 0) lun->pr_key_count++; - } + lun->pr_keys[msg->pr.pr_info.residx] = + scsi_8btou64(msg->pr.pr_info.sa_res_key); lun->PRGeneration++; - memcpy(&lun->per_res[msg->pr.pr_info.residx].res_key, - msg->pr.pr_info.sa_res_key, - sizeof(struct scsi_per_res_key)); break; case CTL_PR_UNREG_KEY: - lun->per_res[msg->pr.pr_info.residx].registered = 0; - memset(&lun->per_res[msg->pr.pr_info.residx].res_key, - 0, sizeof(struct scsi_per_res_key)); + lun->pr_keys[msg->pr.pr_info.residx] = 0; lun->pr_key_count--; /* XXX Need to see if the reservation has been released */ @@ -8958,8 +8875,8 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) */ for (i = 0; i < CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i+ - persis_offset].registered == 0) + if (lun->pr_keys[i+ + persis_offset] == 0) continue; lun->pending_ua[i] |= @@ -8992,7 +8909,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) if (lun->res_type != SPR_TYPE_EX_AC && lun->res_type != SPR_TYPE_WR_EX) { for (i = 0; i < CTL_MAX_INITIATORS; i++) - if (lun->per_res[i+persis_offset].registered) + if (lun->pr_keys[i+persis_offset] != 0) lun->pending_ua[i] |= CTL_UA_RES_RELEASE; } @@ -9012,7 +8929,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) lun->pr_res_idx = CTL_PR_NO_RESERVATION; for (i=0; i < 2*CTL_MAX_INITIATORS; i++) { - if (lun->per_res[i].registered == 0) + if (lun->pr_keys[i] == 0) continue; if (!persis_offset && i < CTL_MAX_INITIATORS) @@ -9021,9 +8938,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg) && i >= persis_offset) lun->pending_ua[i-persis_offset] |= CTL_UA_RES_PREEMPT; - memset(&lun->per_res[i].res_key, 0, - sizeof(struct scsi_per_res_key)); - lun->per_res[i].registered = 0; + lun->pr_keys[i] = 0; } lun->PRGeneration++; break; @@ -9062,7 +8977,7 @@ ctl_read_write(struct ctl_scsiio *ctsio) && residx != lun->pr_res_idx) || ((lun->res_type == SPR_TYPE_EX_AC_RO || lun->res_type == SPR_TYPE_EX_AC_AR) - && !lun->per_res[residx].registered)) { + && lun->pr_keys[residx] == 0)) { ctl_set_reservation_conflict(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -11379,7 +11294,7 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, * type reservations are checked in the particular command * for a conflict. Read and SSU are the only ones. */ - if (!lun->per_res[residx].registered + if (lun->pr_keys[residx] == 0 || (residx != lun->pr_res_idx && lun->res_type < 4)) { ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; ctsio->io_hdr.status = CTL_SCSI_ERROR; diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index 4f22250..aeea63d 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -353,11 +353,6 @@ typedef enum { CTL_PR_FLAG_ACTIVE_RES = 0x02 } ctl_per_res_flags; -struct ctl_per_res_info { - struct scsi_per_res_key res_key; - uint8_t registered; -}; - #define CTL_PR_ALL_REGISTRANTS 0xFFFFFFFF #define CTL_PR_NO_RESERVATION 0xFFFFFFF0 @@ -398,8 +393,8 @@ struct ctl_lun { struct ctl_mode_pages mode_pages; struct ctl_lun_io_stats stats; uint32_t res_idx; - struct ctl_per_res_info per_res[2*CTL_MAX_INITIATORS]; unsigned int PRGeneration; + uint64_t pr_keys[2*CTL_MAX_INITIATORS]; int pr_key_count; uint32_t pr_res_idx; uint8_t res_type; |