summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-10-10 17:37:15 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 20:55:45 -0800
commitd977f4377fbc396b888e12fdb3b13118b09ca7db (patch)
treef3de282b1df951ec599908e24590dbcbac5b9047
parent019c4ca621488739b1bfb7597a14ac7f0cbcc908 (diff)
downloadlinux-d977f4377fbc396b888e12fdb3b13118b09ca7db.tar.gz
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: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/target/target_core_configfs.c158
-rw-r--r--drivers/target/target_core_device.c3
-rw-r--r--drivers/target/target_core_pr.c192
-rw-r--r--drivers/target/target_core_pr.h2
-rw-r--r--drivers/target/target_core_spc.c19
-rw-r--r--drivers/target/target_core_transport.c22
-rw-r--r--include/target/target_core_base.h29
7 files changed, 127 insertions, 298 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 7272016ed05f..3d5570da41eb 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -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;
+	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);
+	} else {
+		len = sprintf(page, "No SPC-2 Reservation holder\n");
 	}
-	*len += sprintf(page + *len, "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;
+	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) {
+	if (pr_reg) {
+		len = sprintf(page, "SPC-3 Reservation Type: %s\n",
+			core_scsi3_pr_dump_type(pr_reg->pr_res_type));
+	} else {
 		len = sprintf(page, "No SPC-3 Reservation holder\n");
-		spin_unlock(&dev->dev_reservation_lock);
-		return len;
 	}
-	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);
 
+	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) {
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 6a27e7fd33fb..4ae1d3913821 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -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;
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 2b289891672f..f561a08ff8e5 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -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;
+		break;
 	}
 
-	return 1;
-}
-
-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)
-{
-	return 0;
-}
+	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;
+	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);
 
-	/*
-	 * 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);
-	}
+	return ret;
 }
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h
index 78451437d2c2..7616f2690ca0 100644
--- a/drivers/target/target_core_pr.h
+++ b/drivers/target/target_core_pr.h
@@ -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 */
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 8ca62631ec7f..862e4347f68f 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -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,8 +1017,7 @@ 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;
+		cmd->execute_cmd = target_scsi2_reservation_release;
 		break;
 	case RESERVE:
 	case RESERVE_10:
@@ -1033,15 +1030,7 @@ 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;
+		cmd->execute_cmd = target_scsi2_reservation_reserve;
 		break;
 	case REQUEST_SENSE:
 		*size = cdb[4];
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 757e3777ce79..e996bdf480cf 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1103,7 +1103,6 @@ int target_setup_cmd_from_cdb(
 	unsigned char *cdb)
 {
 	struct se_device *dev = cmd->se_dev;
-	u32 pr_reg_type = 0;
 	u8 alua_ascq = 0;
 	unsigned long flags;
 	int ret;
@@ -1180,20 +1179,13 @@ int target_setup_cmd_from_cdb(
 	/*
 	 * Check status for SPC-3 Persistent Reservations
 	 */
-	if (dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) {
-		if (dev->t10_pr.pr_ops.t10_seq_non_holder(
-					cmd, cdb, pr_reg_type) != 0) {
-			cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-			cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
-			cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
-			cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
-			return -EBUSY;
-		}
-		/*
-		 * This means the CDB is allowed for the SCSI Initiator port
-		 * when said port is *NOT* holding the legacy SPC-2 or
-		 * SPC-3 Persistent Reservation.
-		 */
+	ret = target_check_reservation(cmd);
+	if (ret) {
+		cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
+		cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
+		cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
+		cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+		return ret;
 	}
 
 	ret = dev->transport->parse_cdb(cmd);
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 15af1307d064..892a93dec19c 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -93,8 +93,6 @@
  */
 #define DA_EMULATE_TPWS				0
 /* No Emulation for PSCSI by default */
-#define DA_EMULATE_RESERVATIONS			0
-/* No Emulation for PSCSI by default */
 #define DA_EMULATE_ALUA				0
 /* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */
 #define DA_ENFORCE_PR_ISIDS			1
@@ -333,18 +331,6 @@ struct t10_wwn {
 	struct list_head t10_vpd_list;
 };
 
-
-/*
- * Used by TCM Core internally to signal if >= SPC-3 persistent reservations
- * emulation is enabled or disabled, or running in with TCM/pSCSI passthrough
- * mode
- */
-typedef enum {
-	SPC_PASSTHROUGH,
-	SPC2_RESERVATIONS,
-	SPC3_PERSISTENT_RESERVATIONS
-} t10_reservations_index_t;
-
 struct t10_pr_registration {
 	/* Used for fabrics that contain WWN+ISID */
 #define PR_REG_ISID_LEN				16
@@ -386,18 +372,6 @@ struct t10_pr_registration {
 	struct list_head pr_reg_atp_mem_list;
 };
 
-/*
- * This set of function pointer ops is set based upon SPC3_PERSISTENT_RESERVATIONS,
- * SPC2_RESERVATIONS or SPC_PASSTHROUGH in drivers/target/target_core_pr.c:
- * core_setup_reservations()
- */
-struct t10_reservation_ops {
-	int (*t10_reservation_check)(struct se_cmd *, u32 *);
-	int (*t10_seq_non_holder)(struct se_cmd *, unsigned char *, u32);
-	int (*t10_pr_register)(struct se_cmd *);
-	int (*t10_pr_clear)(struct se_cmd *);
-};
-
 struct t10_reservation {
 	/* Reservation effects all target ports */
 	int pr_all_tg_pt;
@@ -408,7 +382,6 @@ struct t10_reservation {
 #define PR_APTPL_BUF_LEN			8192
 	u32 pr_aptpl_buf_len;
 	u32 pr_generation;
-	t10_reservations_index_t res_type;
 	spinlock_t registration_lock;
 	spinlock_t aptpl_reg_lock;
 	/*
@@ -424,7 +397,6 @@ struct t10_reservation {
 	struct se_node_acl *pr_res_holder;
 	struct list_head registration_list;
 	struct list_head aptpl_reg_list;
-	struct t10_reservation_ops pr_ops;
 };
 
 struct se_tmr_req {
@@ -633,7 +605,6 @@ struct se_dev_attrib {
 	int		emulate_tas;
 	int		emulate_tpu;
 	int		emulate_tpws;
-	int		emulate_reservations;
 	int		emulate_alua;
 	int		enforce_pr_isids;
 	int		is_nonrot;