summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c205
-rw-r--r--sys/cam/ctl/ctl_private.h7
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;
OpenPOWER on IntegriCloud