From 115dc0c762b35a56002d1ed2d45998addebe1503 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 27 Oct 2014 09:26:24 +0000 Subject: [PATCH] Reduce code duplication around Write Exclusive persistent reservation. While there, allow some more commands to pass persistent reservation. MFC after: 1 week --- sys/cam/ctl/ctl.c | 91 +++++-------------------------------- sys/cam/ctl/ctl_cmd_table.c | 42 +++++++++-------- sys/cam/ctl/ctl_private.h | 1 + 3 files changed, 37 insertions(+), 97 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 0f34b7561b7c..b3c9b06fba63 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -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; } diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index a9bd50070d53..0180cecff261 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -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}}, diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index bb9a32d5616b..e3dcf7079acb 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -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,