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

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

target: simplify reservations code



We do not support host-level reservations for the pscsi backend, and all
virtual backends are newere than SCSI-2, so just make the combined
SPC-3 + SCSI-2 support the only supported variant and kill the switches
for the different implementations, given that this code handles the no-op
version just fine.

(hch: Update DRF_SPC2_RESERVATIONS lock usage)

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 019c4ca6
Loading
Loading
Loading
Loading
+52 −106
Original line number Diff line number Diff line
@@ -970,13 +970,8 @@ static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \
	__CONFIGFS_EATTR_RO(_name,					\
	target_core_dev_pr_show_attr_##_name);

/*
 * res_holder
 */
static ssize_t target_core_dev_pr_show_spc3_res(
	struct se_device *dev,
	char *page,
	ssize_t *len)
static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev,
		char *page)
{
	struct se_node_acl *se_nacl;
	struct t10_pr_registration *pr_reg;
@@ -985,68 +980,52 @@ static ssize_t target_core_dev_pr_show_spc3_res(

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);

	spin_lock(&dev->dev_reservation_lock);
	pr_reg = dev->dev_pr_res_holder;
	if (!pr_reg) {
		*len += sprintf(page + *len, "No SPC-3 Reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		return *len;
	}
	if (!pr_reg)
		return sprintf(page, "No SPC-3 Reservation holder\n");

	se_nacl = pr_reg->pr_reg_nacl;
	prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
				PR_REG_ISID_ID_LEN);

	*len += sprintf(page + *len, "SPC-3 Reservation: %s Initiator: %s%s\n",
	return sprintf(page, "SPC-3 Reservation: %s Initiator: %s%s\n",
		se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
		se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : "");
	spin_unlock(&dev->dev_reservation_lock);

	return *len;
}

static ssize_t target_core_dev_pr_show_spc2_res(
	struct se_device *dev,
	char *page,
	ssize_t *len)
static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev,
		char *page)
{
	struct se_node_acl *se_nacl;
	ssize_t len;

	spin_lock(&dev->dev_reservation_lock);
	se_nacl = dev->dev_reserved_node_acl;
	if (!se_nacl) {
		*len += sprintf(page + *len, "No SPC-2 Reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		return *len;
	}
	*len += sprintf(page + *len, "SPC-2 Reservation: %s Initiator: %s\n",
	if (se_nacl) {
		len = sprintf(page,
			      "SPC-2 Reservation: %s Initiator: %s\n",
			      se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
			      se_nacl->initiatorname);
	spin_unlock(&dev->dev_reservation_lock);

	return *len;
	} else {
		len = sprintf(page, "No SPC-2 Reservation holder\n");
	}
	return len;
}

static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev,
		char *page)
{
	ssize_t len = 0;
	int ret;

	switch (dev->t10_pr.res_type) {
	case SPC3_PERSISTENT_RESERVATIONS:
		target_core_dev_pr_show_spc3_res(dev, page, &len);
		break;
	case SPC2_RESERVATIONS:
		target_core_dev_pr_show_spc2_res(dev, page, &len);
		break;
	case SPC_PASSTHROUGH:
		len += sprintf(page+len, "Passthrough\n");
		break;
	default:
		len += sprintf(page+len, "Unknown\n");
		break;
	}
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return sprintf(page, "Passthrough\n");

	return len;
	spin_lock(&dev->dev_reservation_lock);
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		ret = target_core_dev_pr_show_spc2_res(dev, page);
	else
		ret = target_core_dev_pr_show_spc3_res(dev, page);
	spin_unlock(&dev->dev_reservation_lock);
	return ret;
}

SE_DEV_PR_ATTR_RO(res_holder);
@@ -1054,31 +1033,20 @@ SE_DEV_PR_ATTR_RO(res_holder);
static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
		struct se_device *dev, char *page)
{
	struct t10_pr_registration *pr_reg;
	ssize_t len = 0;

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
		return len;

	spin_lock(&dev->dev_reservation_lock);
	pr_reg = dev->dev_pr_res_holder;
	if (!pr_reg) {
	if (!dev->dev_pr_res_holder) {
		len = sprintf(page, "No SPC-3 Reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		return len;
	}
	/*
	 * See All Target Ports (ALL_TG_PT) bit in spcr17, section 6.14.3
	 * Basic PERSISTENT RESERVER OUT parameter list, page 290
	 */
	if (pr_reg->pr_reg_all_tg_pt)
	} else if (dev->dev_pr_res_holder->pr_reg_all_tg_pt) {
		len = sprintf(page, "SPC-3 Reservation: All Target"
			" Ports registration\n");
	else
	} else {
		len = sprintf(page, "SPC-3 Reservation: Single"
			" Target Port registration\n");
	spin_unlock(&dev->dev_reservation_lock);
	}

	spin_unlock(&dev->dev_reservation_lock);
	return len;
}

@@ -1087,9 +1055,6 @@ SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts);
static ssize_t target_core_dev_pr_show_attr_res_pr_generation(
		struct se_device *dev, char *page)
{
	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
		return 0;

	return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation);
}

@@ -1108,16 +1073,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
	struct target_core_fabric_ops *tfo;
	ssize_t len = 0;

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
		return len;

	spin_lock(&dev->dev_reservation_lock);
	pr_reg = dev->dev_pr_res_holder;
	if (!pr_reg) {
		len = sprintf(page, "No SPC-3 Reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		return len;
		goto out_unlock;
	}

	se_nacl = pr_reg->pr_reg_nacl;
	se_tpg = se_nacl->se_tpg;
	lun = pr_reg->pr_reg_tg_pt_lun;
@@ -1131,8 +1093,9 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
		" %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi,
		tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg),
		tfo->get_fabric_name(), lun->unpacked_lun);
	spin_unlock(&dev->dev_reservation_lock);

out_unlock:
	spin_unlock(&dev->dev_reservation_lock);
	return len;
}

@@ -1148,9 +1111,6 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
	ssize_t len = 0;
	int reg_count = 0, prf_isid;

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
		return len;

	len += sprintf(page+len, "SPC-3 PR Registrations:\n");

	spin_lock(&dev->t10_pr.registration_lock);
@@ -1190,20 +1150,16 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_type(
	struct t10_pr_registration *pr_reg;
	ssize_t len = 0;

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
		return len;

	spin_lock(&dev->dev_reservation_lock);
	pr_reg = dev->dev_pr_res_holder;
	if (!pr_reg) {
		len = sprintf(page, "No SPC-3 Reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		return len;
	}
	if (pr_reg) {
		len = sprintf(page, "SPC-3 Reservation Type: %s\n",
			core_scsi3_pr_dump_type(pr_reg->pr_res_type));
	spin_unlock(&dev->dev_reservation_lock);
	} else {
		len = sprintf(page, "No SPC-3 Reservation holder\n");
	}

	spin_unlock(&dev->dev_reservation_lock);
	return len;
}

@@ -1212,24 +1168,12 @@ SE_DEV_PR_ATTR_RO(res_pr_type);
static ssize_t target_core_dev_pr_show_attr_res_type(
		struct se_device *dev, char *page)
{
	ssize_t len = 0;

	switch (dev->t10_pr.res_type) {
	case SPC3_PERSISTENT_RESERVATIONS:
		len = sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n");
		break;
	case SPC2_RESERVATIONS:
		len = sprintf(page, "SPC2_RESERVATIONS\n");
		break;
	case SPC_PASSTHROUGH:
		len = sprintf(page, "SPC_PASSTHROUGH\n");
		break;
	default:
		len = sprintf(page, "UNKNOWN\n");
		break;
	}

	return len;
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return sprintf(page, "SPC_PASSTHROUGH\n");
	else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return sprintf(page, "SPC2_RESERVATIONS\n");
	else
		return sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n");
}

SE_DEV_PR_ATTR_RO(res_type);
@@ -1237,7 +1181,7 @@ SE_DEV_PR_ATTR_RO(res_type);
static ssize_t target_core_dev_pr_show_attr_res_aptpl_active(
		struct se_device *dev, char *page)
{
	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return 0;

	return sprintf(page, "APTPL Bit Status: %s\n",
@@ -1252,7 +1196,7 @@ SE_DEV_PR_ATTR_RO(res_aptpl_active);
static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata(
		struct se_device *dev, char *page)
{
	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return 0;

	return sprintf(page, "Ready to process PR APTPL metadata..\n");
@@ -1299,7 +1243,9 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
	u16 port_rpti = 0, tpgt = 0;
	u8 type = 0, scope;

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return 0;
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return 0;

	if (dev->export_count) {
+0 −3
Original line number Diff line number Diff line
@@ -1398,7 +1398,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
	dev->dev_attrib.emulate_tas = DA_EMULATE_TAS;
	dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU;
	dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
	dev->dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
	dev->dev_attrib.emulate_alua = DA_EMULATE_ALUA;
	dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
	dev->dev_attrib.is_nonrot = DA_IS_NONROT;
@@ -1447,8 +1446,6 @@ int target_configure_device(struct se_device *dev)
	dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);
	dev->creation_time = get_jiffies_64();

	core_setup_reservations(dev);

	ret = core_setup_alua(dev);
	if (ret)
		goto out;
+63 −129
Original line number Diff line number Diff line
@@ -68,49 +68,32 @@ int core_pr_dump_initiator_port(
static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
			struct t10_pr_registration *, int);

static int core_scsi2_reservation_seq_non_holder(
	struct se_cmd *cmd,
	unsigned char *cdb,
	u32 pr_reg_type)
static int target_scsi2_reservation_check(struct se_cmd *cmd)
{
	switch (cdb[0]) {
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;

	switch (cmd->t_task_cdb[0]) {
	case INQUIRY:
	case RELEASE:
	case RELEASE_10:
		return 0;
	default:
		return 1;
	}

	return 1;
		break;
	}

static int core_scsi2_reservation_check(struct se_cmd *cmd, u32 *pr_reg_type)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;
	int ret;

	if (!sess)
	if (!dev->dev_reserved_node_acl || !sess)
		return 0;

	spin_lock(&dev->dev_reservation_lock);
	if (!dev->dev_reserved_node_acl || !sess) {
		spin_unlock(&dev->dev_reservation_lock);
		return 0;
	}
	if (dev->dev_reserved_node_acl != sess->se_node_acl) {
		spin_unlock(&dev->dev_reservation_lock);
		return -EINVAL;
	}
	if (!(dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID)) {
		spin_unlock(&dev->dev_reservation_lock);
		return 0;
	if (dev->dev_reserved_node_acl != sess->se_node_acl)
		return -EBUSY;

	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
		if (dev->dev_res_bin_isid != sess->sess_bin_isid)
			return -EBUSY;
	}
	ret = (dev->dev_res_bin_isid == sess->sess_bin_isid) ? 0 : -EINVAL;
	spin_unlock(&dev->dev_reservation_lock);

	return ret;
	return 0;
}

static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
@@ -123,12 +106,8 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
	struct se_device *dev = cmd->se_dev;
	struct t10_pr_registration *pr_reg;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	int crh = (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
	int conflict = 0;

	if (!crh)
		return -EINVAL;

	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
			se_sess);
	if (pr_reg) {
@@ -319,9 +298,9 @@ out:
 */
static int core_scsi3_pr_seq_non_holder(
	struct se_cmd *cmd,
	unsigned char *cdb,
	u32 pr_reg_type)
{
	unsigned char *cdb = cmd->t_task_cdb;
	struct se_dev_entry *se_deve;
	struct se_session *se_sess = cmd->se_sess;
	int other_cdb = 0, ignore_reg;
@@ -330,17 +309,11 @@ static int core_scsi3_pr_seq_non_holder(
	int we = 0; /* Write Exclusive */
	int legacy = 0; /* Act like a legacy device and return
			 * RESERVATION CONFLICT on some CDBs */
	/*
	 * A legacy SPC-2 reservation is being held.
	 */
	if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return core_scsi2_reservation_seq_non_holder(cmd,
					cdb, pr_reg_type);

	se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
	/*
	 * Determine if the registration should be ignored due to
	 * non-matching ISIDs in core_scsi3_pr_reservation_check().
	 * non-matching ISIDs in target_scsi3_pr_reservation_check().
	 */
	ignore_reg = (pr_reg_type & 0x80000000);
	if (ignore_reg)
@@ -563,6 +536,36 @@ static int core_scsi3_pr_seq_non_holder(
	return 1; /* Conflict by default */
}

static int target_scsi3_pr_reservation_check(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;
	u32 pr_reg_type;

	if (!dev->dev_pr_res_holder)
		return 0;

	pr_reg_type = dev->dev_pr_res_holder->pr_res_type;
	cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key;
	if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl)
		goto check_nonholder;

	if (dev->dev_pr_res_holder->isid_present_at_reg) {
		if (dev->dev_pr_res_holder->pr_reg_bin_isid !=
		    sess->sess_bin_isid) {
			pr_reg_type |= 0x80000000;
			goto check_nonholder;
		}
	}

	return 0;

check_nonholder:
	if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type))
		return -EBUSY;
	return 0;
}

static u32 core_scsi3_pr_generation(struct se_device *dev)
{
	u32 prg;
@@ -583,50 +586,6 @@ static u32 core_scsi3_pr_generation(struct se_device *dev)
	return prg;
}

static int core_scsi3_pr_reservation_check(
	struct se_cmd *cmd,
	u32 *pr_reg_type)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;
	int ret;

	if (!sess)
		return 0;
	/*
	 * A legacy SPC-2 reservation is being held.
	 */
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return core_scsi2_reservation_check(cmd, pr_reg_type);

	spin_lock(&dev->dev_reservation_lock);
	if (!dev->dev_pr_res_holder) {
		spin_unlock(&dev->dev_reservation_lock);
		return 0;
	}
	*pr_reg_type = dev->dev_pr_res_holder->pr_res_type;
	cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key;
	if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) {
		spin_unlock(&dev->dev_reservation_lock);
		return -EINVAL;
	}
	if (!dev->dev_pr_res_holder->isid_present_at_reg) {
		spin_unlock(&dev->dev_reservation_lock);
		return 0;
	}
	ret = (dev->dev_pr_res_holder->pr_reg_bin_isid ==
	       sess->sess_bin_isid) ? 0 : -EINVAL;
	/*
	 * Use bit in *pr_reg_type to notify ISID mismatch in
	 * core_scsi3_pr_seq_non_holder().
	 */
	if (ret != 0)
		*pr_reg_type |= 0x80000000;
	spin_unlock(&dev->dev_reservation_lock);

	return ret;
}

static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
	struct se_device *dev,
	struct se_node_acl *nacl,
@@ -998,7 +957,7 @@ int core_scsi3_check_aptpl_registration(
	struct se_node_acl *nacl = lun_acl->se_lun_nacl;
	struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun];

	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return 0;

	return __core_scsi3_check_aptpl_registration(dev, tpg, lun,
@@ -4343,49 +4302,24 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
	return ret;
}

static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)
int target_check_reservation(struct se_cmd *cmd)
{
	return 0;
}
	struct se_device *dev = cmd->se_dev;
	int ret;

static int core_pt_seq_non_holder(
	struct se_cmd *cmd,
	unsigned char *cdb,
	u32 pr_reg_type)
{
	if (!cmd->se_sess)
		return 0;
	if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)
		return 0;
	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
		return 0;
}

void core_setup_reservations(struct se_device *dev)
{
	struct t10_reservation *rest = &dev->t10_pr;

	/*
	 * If this device is from Target_Core_Mod/pSCSI, use the reservations
	 * of the Underlying SCSI hardware.  In Linux/SCSI terms, this can
	 * cause a problem because libata and some SATA RAID HBAs appear
	 * under Linux/SCSI, but to emulate reservations themselves.
	 */
	if ((dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) ||
	    (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV &&
	     !dev->dev_attrib.emulate_reservations)) {
		rest->res_type = SPC_PASSTHROUGH;
		rest->pr_ops.t10_reservation_check = &core_pt_reservation_check;
		rest->pr_ops.t10_seq_non_holder = &core_pt_seq_non_holder;
		pr_debug("%s: Using SPC_PASSTHROUGH, no reservation"
			" emulation\n", dev->transport->name);
	} else if (dev->transport->get_device_rev(dev) >= SCSI_3) {
		rest->res_type = SPC3_PERSISTENT_RESERVATIONS;
		rest->pr_ops.t10_reservation_check = &core_scsi3_pr_reservation_check;
		rest->pr_ops.t10_seq_non_holder = &core_scsi3_pr_seq_non_holder;
		pr_debug("%s: Using SPC3_PERSISTENT_RESERVATIONS"
			" emulation\n", dev->transport->name);
	} else {
		rest->res_type = SPC2_RESERVATIONS;
		rest->pr_ops.t10_reservation_check = &core_scsi2_reservation_check;
		rest->pr_ops.t10_seq_non_holder =
				&core_scsi2_reservation_seq_non_holder;
		pr_debug("%s: Using SPC2_RESERVATIONS emulation\n",
			dev->transport->name);
	}
	spin_lock(&dev->dev_reservation_lock);
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		ret = target_scsi2_reservation_check(cmd);
	else
		ret = target_scsi3_pr_reservation_check(cmd);
	spin_unlock(&dev->dev_reservation_lock);

	return ret;
}
+1 −1
Original line number Diff line number Diff line
@@ -63,6 +63,6 @@ extern unsigned char *core_scsi3_pr_dump_type(int);

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

#endif /* TARGET_CORE_PR_H */
+4 −15
Original line number Diff line number Diff line
@@ -1003,14 +1003,12 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
		*size = (cdb[7] << 8) + cdb[8];
		break;
	case PERSISTENT_RESERVE_IN:
		if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
			cmd->execute_cmd = target_scsi3_emulate_pr_in;
		*size = (cdb[7] << 8) + cdb[8];
		cmd->execute_cmd = target_scsi3_emulate_pr_in;
		break;
	case PERSISTENT_RESERVE_OUT:
		if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
			cmd->execute_cmd = target_scsi3_emulate_pr_out;
		*size = (cdb[7] << 8) + cdb[8];
		cmd->execute_cmd = target_scsi3_emulate_pr_out;
		break;
	case RELEASE:
	case RELEASE_10:
@@ -1019,7 +1017,6 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
		else
			*size = cmd->data_length;

		if (dev->t10_pr.res_type != SPC_PASSTHROUGH)
		cmd->execute_cmd = target_scsi2_reservation_release;
		break;
	case RESERVE:
@@ -1033,14 +1030,6 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
		else
			*size = cmd->data_length;

		/*
		 * Setup the legacy emulated handler for SPC-2 and
		 * >= SPC-3 compatible reservation handling (CRH=1)
		 * Otherwise, we assume the underlying SCSI logic is
		 * is running in SPC_PASSTHROUGH, and wants reservations
		 * emulation disabled.
		 */
		if (dev->t10_pr.res_type != SPC_PASSTHROUGH)
		cmd->execute_cmd = target_scsi2_reservation_reserve;
		break;
	case REQUEST_SENSE:
Loading