Reduce code duplication around Write Exclusive persistent reservation.

While there, allow some more commands to pass persistent reservation.

MFC after:	1 week
This commit is contained in:
mav 2014-10-27 09:26:24 +00:00
parent 50ca982286
commit 1a960f7ebe
3 changed files with 37 additions and 97 deletions

View File

@ -5341,8 +5341,7 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio)
mtx_lock(&lun->lun_lock);
if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx != residx)) {
ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
ctsio->io_hdr.status = CTL_SCSI_ERROR;
ctl_set_reservation_conflict(ctsio);
goto bailout;
}
@ -5693,24 +5692,6 @@ ctl_read_buffer(struct ctl_scsiio *ctsio)
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_read_buffer *)ctsio->cdb;
if (lun->flags & CTL_LUN_PR_RESERVED) {
uint32_t residx;
/*
* XXX KDM need a lock here.
*/
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
if ((lun->res_type == SPR_TYPE_EX_AC
&& residx != lun->pr_res_idx)
|| ((lun->res_type == SPR_TYPE_EX_AC_RO
|| lun->res_type == SPR_TYPE_EX_AC_AR)
&& lun->pr_keys[residx] == 0)) {
ctl_set_reservation_conflict(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
}
if ((cdb->byte2 & RWB_MODE) != RWB_MODE_DATA &&
(cdb->byte2 & RWB_MODE) != RWB_MODE_ECHO_DESCR &&
(cdb->byte2 & RWB_MODE) != RWB_MODE_DESCR) {
@ -6642,24 +6623,6 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
else
control_dev = 0;
if (lun->flags & CTL_LUN_PR_RESERVED) {
uint32_t residx;
/*
* XXX KDM need a lock here.
*/
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
if ((lun->res_type == SPR_TYPE_EX_AC
&& residx != lun->pr_res_idx)
|| ((lun->res_type == SPR_TYPE_EX_AC_RO
|| lun->res_type == SPR_TYPE_EX_AC_AR)
&& lun->pr_keys[residx] == 0)) {
ctl_set_reservation_conflict(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
}
switch (ctsio->cdb[0]) {
case MODE_SENSE_6: {
struct scsi_mode_sense_6 *cdb;
@ -7196,23 +7159,6 @@ ctl_read_defect(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_read_defect\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
if (lun->flags & CTL_LUN_PR_RESERVED) {
uint32_t residx;
/*
* XXX KDM need a lock here.
*/
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
if ((lun->res_type == SPR_TYPE_EX_AC
&& residx != lun->pr_res_idx)
|| ((lun->res_type == SPR_TYPE_EX_AC_RO
|| lun->res_type == SPR_TYPE_EX_AC_AR)
&& lun->pr_keys[residx] == 0)) {
ctl_set_reservation_conflict(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
}
if (ctsio->cdb[0] == READ_DEFECT_DATA_10) {
ccb10 = (struct scsi_read_defect_data_10 *)&ctsio->cdb;
@ -8906,24 +8852,6 @@ ctl_read_write(struct ctl_scsiio *ctsio)
isread = ctsio->cdb[0] == READ_6 || ctsio->cdb[0] == READ_10
|| ctsio->cdb[0] == READ_12 || ctsio->cdb[0] == READ_16;
if (lun->flags & CTL_LUN_PR_RESERVED && isread) {
uint32_t residx;
/*
* XXX KDM need a lock here.
*/
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
if ((lun->res_type == SPR_TYPE_EX_AC
&& residx != lun->pr_res_idx)
|| ((lun->res_type == SPR_TYPE_EX_AC_RO
|| lun->res_type == SPR_TYPE_EX_AC_AR)
&& lun->pr_keys[residx] == 0)) {
ctl_set_reservation_conflict(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
}
switch (ctsio->cdb[0]) {
case READ_6:
case WRITE_6: {
@ -11225,15 +11153,21 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
if ((lun->flags & CTL_LUN_RESERVED)
&& ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_RESV) == 0)) {
if (lun->res_idx != residx) {
ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
ctsio->io_hdr.status = CTL_SCSI_ERROR;
ctl_set_reservation_conflict(ctsio);
retval = 1;
goto bailout;
}
}
if ((lun->flags & CTL_LUN_PR_RESERVED)
&& ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV) == 0)) {
if ((lun->flags & CTL_LUN_PR_RESERVED) == 0 ||
(entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_RESV)) {
/* No reservation or command is allowed. */;
} else if ((entry->flags & CTL_CMD_FLAG_ALLOW_ON_PR_WRESV) &&
(lun->res_type == SPR_TYPE_WR_EX ||
lun->res_type == SPR_TYPE_WR_EX_RO ||
lun->res_type == SPR_TYPE_WR_EX_AR)) {
/* The command is allowed for Write Exclusive resv. */;
} else {
/*
* if we aren't registered or it's a res holder type
* reservation and this isn't the res holder then set a
@ -11244,8 +11178,7 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
*/
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;
ctl_set_reservation_conflict(ctsio);
retval = 1;
goto bailout;
}

View File

@ -259,7 +259,8 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] =
/* 10 POPULATE TOKEN */
{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT,
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
16, { 0x10, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -347,7 +348,8 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] =
/* 05 RECEIVE COPY STATUS (LID4) */
{ctl_receive_copy_status_lid4, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_FLAG_DATA_IN,
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x05, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -357,14 +359,16 @@ const struct ctl_cmd_entry ctl_cmd_table_84[32] =
/* 07 RECEIVE ROD TOKEN INFORMATION */
{ctl_receive_rod_token_information, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_FLAG_DATA_IN,
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x07, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
/* 08 REPORT ALL ROD TOKENS */
{ctl_report_all_rod_tokens, CTL_SERIDX_RD_CAP,
CTL_CMD_FLAG_OK_ON_BOTH |
CTL_FLAG_DATA_IN,
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
16, {0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
};
@ -472,7 +476,8 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_CMD_FLAG_OK_ON_INOPERABLE |
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN,
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
12, {0x0a, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -510,7 +515,8 @@ const struct ctl_cmd_entry ctl_cmd_table_a3[32] =
CTL_CMD_FLAG_OK_ON_INOPERABLE |
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN,
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_LUN_PAT_NONE,
12, {0x0f, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -561,7 +567,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 08 READ(6) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}},
/* 09 */
@ -653,7 +659,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE, 6, {0x08, 0xff, 0xff, 0xff, 0x07}},
/* 1B START STOP UNIT */
@ -710,7 +716,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 28 READ(10) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
@ -739,7 +745,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 2F VERIFY(10) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
10, {0x16, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
@ -770,7 +776,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 37 READ DEFECT DATA(10) */
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
10, {0, 0x1f, 0, 0, 0, 0, 0xff, 0xff, 0x07}},
@ -792,7 +798,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 3C READ BUFFER */
{ctl_read_buffer, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_BOTH |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
10, {0x1f, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07}},
@ -918,7 +924,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
CTL_CMD_FLAG_OK_ON_OFFLINE |
CTL_CMD_FLAG_OK_ON_SECONDARY |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE, 10, {0x18, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0x07} },
/* 5B CLOSE TRACK/SESSION */
@ -1062,7 +1068,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 88 READ(16) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -1097,7 +1103,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* 8F VERIFY(16) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
16, {0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -1199,7 +1205,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* A8 READ(12) */
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -1228,7 +1234,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* AF VERIFY(12) */
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_OUT |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
12, {0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
@ -1256,7 +1262,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
/* B7 READ DEFECT DATA(12) */
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
CTL_FLAG_DATA_IN |
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
CTL_LUN_PAT_NONE,
12, {0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},

View File

@ -144,6 +144,7 @@ typedef enum {
CTL_CMD_FLAG_NO_SENSE = 0x0010,
CTL_CMD_FLAG_OK_ON_ALL_LUNS = 0x0020,
CTL_CMD_FLAG_ALLOW_ON_RESV = 0x0040,
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV = 0x0080,
CTL_CMD_FLAG_OK_ON_PROC = 0x0100,
CTL_CMD_FLAG_OK_ON_SLUN = 0x0200,
CTL_CMD_FLAG_OK_ON_BOTH = 0x0300,