From 617c0e06c1b30b799d8b25f92eefdc1b098cb9f8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 3 Nov 2011 17:50:41 -0400 Subject: target: split core_scsi3_emulate_pr Split core_scsi2_emulate_crh into one routine each for the PERSISTENT_RESERVE_IN and PERSISTENT_RESERVE_OUT side. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_pr.c | 62 +++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'drivers/target/target_core_pr.c') diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 830953a743d6..34403e80b87c 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -3734,12 +3734,30 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb) /* * See spc4r17 section 6.14 Table 170 */ -static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb) +int target_scsi3_emulate_pr_out(struct se_cmd *cmd) { + unsigned char *cdb = &cmd->t_task_cdb[0]; unsigned char *buf; u64 res_key, sa_res_key; int sa, scope, type, aptpl; int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; + + /* + * Following spc2r20 5.5.1 Reservations overview: + * + * If a logical unit has been reserved by any RESERVE command and is + * still reserved by any initiator, all PERSISTENT RESERVE IN and all + * PERSISTENT RESERVE OUT commands shall conflict regardless of + * initiator or service action and shall terminate with a RESERVATION + * CONFLICT status. + */ + if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) { + pr_err("Received PERSISTENT_RESERVE CDB while legacy" + " SPC-2 reservation is held, returning" + " RESERVATION_CONFLICT\n"); + return PYX_TRANSPORT_RESERVATION_CONFLICT; + } + /* * FIXME: A NULL struct se_session pointer means an this is not coming from * a $FABRIC_MOD's nexus, but from internal passthrough ops. @@ -4185,29 +4203,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) return 0; } -static int core_scsi3_emulate_pr_in(struct se_cmd *cmd, unsigned char *cdb) -{ - switch (cdb[1] & 0x1f) { - case PRI_READ_KEYS: - return core_scsi3_pri_read_keys(cmd); - case PRI_READ_RESERVATION: - return core_scsi3_pri_read_reservation(cmd); - case PRI_REPORT_CAPABILITIES: - return core_scsi3_pri_report_capabilities(cmd); - case PRI_READ_FULL_STATUS: - return core_scsi3_pri_read_full_status(cmd); - default: - pr_err("Unknown PERSISTENT_RESERVE_IN service" - " action: 0x%02x\n", cdb[1] & 0x1f); - return PYX_TRANSPORT_INVALID_CDB_FIELD; - } - -} - -int core_scsi3_emulate_pr(struct se_cmd *cmd) +int target_scsi3_emulate_pr_in(struct se_cmd *cmd) { - unsigned char *cdb = &cmd->t_task_cdb[0]; - struct se_device *dev = cmd->se_dev; /* * Following spc2r20 5.5.1 Reservations overview: * @@ -4217,16 +4214,27 @@ int core_scsi3_emulate_pr(struct se_cmd *cmd) * initiator or service action and shall terminate with a RESERVATION * CONFLICT status. */ - if (dev->dev_flags & DF_SPC2_RESERVATIONS) { + if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) { pr_err("Received PERSISTENT_RESERVE CDB while legacy" " SPC-2 reservation is held, returning" " RESERVATION_CONFLICT\n"); return PYX_TRANSPORT_RESERVATION_CONFLICT; } - return (cdb[0] == PERSISTENT_RESERVE_OUT) ? - core_scsi3_emulate_pr_out(cmd, cdb) : - core_scsi3_emulate_pr_in(cmd, cdb); + switch (cmd->t_task_cdb[1] & 0x1f) { + case PRI_READ_KEYS: + return core_scsi3_pri_read_keys(cmd); + case PRI_READ_RESERVATION: + return core_scsi3_pri_read_reservation(cmd); + case PRI_REPORT_CAPABILITIES: + return core_scsi3_pri_report_capabilities(cmd); + case PRI_READ_FULL_STATUS: + return core_scsi3_pri_read_full_status(cmd); + default: + pr_err("Unknown PERSISTENT_RESERVE_IN service" + " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); + return PYX_TRANSPORT_INVALID_CDB_FIELD; + } } static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) -- cgit v1.2.3