Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 617c0e06 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent eacac00c
Loading
Loading
Loading
Loading
+35 −27
Original line number Diff line number Diff line
@@ -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)
int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
{
	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)
{
	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)
+3 −1
Original line number Diff line number Diff line
@@ -62,7 +62,9 @@ extern void core_scsi3_free_all_registrations(struct se_device *);
extern unsigned char *core_scsi3_pr_dump_type(int);
extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *,
						  struct se_cmd *);
extern int core_scsi3_emulate_pr(struct se_cmd *);

extern int target_scsi3_emulate_pr_in(struct se_cmd *cmd);
extern int target_scsi3_emulate_pr_out(struct se_cmd *cmd);
extern int core_setup_reservations(struct se_device *, int);

#endif /* TARGET_CORE_PR_H */
+7 −4
Original line number Diff line number Diff line
@@ -2842,11 +2842,14 @@ static int transport_generic_cmd_sequencer(
		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
		break;
	case PERSISTENT_RESERVE_IN:
		if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
			cmd->transport_emulate_cdb = target_scsi3_emulate_pr_in;
		size = (cdb[7] << 8) + cdb[8];
		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
		break;
	case PERSISTENT_RESERVE_OUT:
		cmd->transport_emulate_cdb =
			(su_dev->t10_pr.res_type ==
			 SPC3_PERSISTENT_RESERVATIONS) ?
			core_scsi3_emulate_pr : NULL;
		if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
			cmd->transport_emulate_cdb = target_scsi3_emulate_pr_out;
		size = (cdb[7] << 8) + cdb[8];
		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
		break;