// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 * Filename:  target_core_pr.c
 *
 * This file contains SPC-3 compliant persistent reservations and
 * legacy SPC-2 reservations with compatible reservation handling (CRH=1)
 *
 * (c) Copyright 2009-2013 Datera, Inc.
 *
 * Nicholas A. Bellinger <nab@kernel.org>
 *
 ******************************************************************************/

#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <scsi/scsi_proto.h>
#include <asm/unaligned.h>

#include <target/target_core_base.h>
#include <target/target_core_backend.h>
#include <target/target_core_fabric.h>

#include "target_core_internal.h"
#include "target_core_pr.h"
#include "target_core_ua.h"

/*
 * Used for Specify Initiator Ports Capable Bit (SPEC_I_PT)
 */
struct pr_transport_id_holder {
	struct t10_pr_registration *dest_pr_reg;
	struct se_portal_group *dest_tpg;
	struct se_node_acl *dest_node_acl;
	struct se_dev_entry *dest_se_deve;
	struct list_head dest_list;
};

void core_pr_dump_initiator_port(
	struct t10_pr_registration *pr_reg,
	char *buf,
	u32 size)
{
	if (!pr_reg->isid_present_at_reg) {
		buf[0] = '\0';
		return;
	}

	snprintf(buf, size, ",i,0x%s", pr_reg->pr_reg_isid);
}

enum register_type {
	REGISTER,
	REGISTER_AND_IGNORE_EXISTING_KEY,
	REGISTER_AND_MOVE,
};

enum preempt_type {
	PREEMPT,
	PREEMPT_AND_ABORT,
};

static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
					      struct t10_pr_registration *, int, int);

static int is_reservation_holder(
	struct t10_pr_registration *pr_res_holder,
	struct t10_pr_registration *pr_reg)
{
	int pr_res_type;

	if (pr_res_holder) {
		pr_res_type = pr_res_holder->pr_res_type;

		return pr_res_holder == pr_reg ||
		       pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
		       pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG;
	}
	return 0;
}

static sense_reason_t
target_scsi2_reservation_check(struct se_cmd *cmd)
{
	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:
		break;
	}

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

	if (dev->reservation_holder->se_node_acl != sess->se_node_acl)
		return TCM_RESERVATION_CONFLICT;

	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
		if (dev->dev_res_bin_isid != sess->sess_bin_isid)
			return TCM_RESERVATION_CONFLICT;
	}

	return 0;
}

static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
					struct se_node_acl *, struct se_session *);
static void core_scsi3_put_pr_reg(struct t10_pr_registration *);

static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
{
	struct se_session *se_sess = cmd->se_sess;
	struct se_device *dev = cmd->se_dev;
	struct t10_pr_registration *pr_reg;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	int conflict = 0;

	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
			se_sess);
	if (pr_reg) {
		/*
		 * From spc4r17 5.7.3 Exceptions to SPC-2 RESERVE and RELEASE
		 * behavior
		 *
		 * A RESERVE(6) or RESERVE(10) command shall complete with GOOD
		 * status, but no reservation shall be established and the
		 * persistent reservation shall not be changed, if the command
		 * is received from a) and b) below.
		 *
		 * A RELEASE(6) or RELEASE(10) command shall complete with GOOD
		 * status, but the persistent reservation shall not be released,
		 * if the command is received from a) and b)
		 *
		 * a) An I_T nexus that is a persistent reservation holder; or
		 * b) An I_T nexus that is registered if a registrants only or
		 *    all registrants type persistent reservation is present.
		 *
		 * In all other cases, a RESERVE(6) command, RESERVE(10) command,
		 * RELEASE(6) command, or RELEASE(10) command shall be processed
		 * as defined in SPC-2.
		 */
		if (pr_reg->pr_res_holder) {
			core_scsi3_put_pr_reg(pr_reg);
			return 1;
		}
		if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
		    (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
			core_scsi3_put_pr_reg(pr_reg);
			return 1;
		}
		core_scsi3_put_pr_reg(pr_reg);
		conflict = 1;
	} else {
		/*
		 * Following spc2r20 5.5.1 Reservations overview:
		 *
		 * If a logical unit has executed a PERSISTENT RESERVE OUT
		 * command with the REGISTER or the REGISTER AND IGNORE
		 * EXISTING KEY service action and is still registered by any
		 * initiator, all RESERVE commands and all RELEASE commands
		 * regardless of initiator shall conflict and shall terminate
		 * with a RESERVATION CONFLICT status.
		 */
		spin_lock(&pr_tmpl->registration_lock);
		conflict = (list_empty(&pr_tmpl->registration_list)) ? 0 : 1;
		spin_unlock(&pr_tmpl->registration_lock);
	}

	if (conflict) {
		pr_err("Received legacy SPC-2 RESERVE/RELEASE"
			" while active SPC-3 registrations exist,"
			" returning RESERVATION_CONFLICT\n");
		return -EBUSY;
	}

	return 0;
}

void target_release_reservation(struct se_device *dev)
{
	dev->reservation_holder = NULL;
	dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
		dev->dev_res_bin_isid = 0;
		dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID;
	}
}

sense_reason_t
target_scsi2_reservation_release(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;
	struct se_portal_group *tpg;
	int rc;

	if (!sess || !sess->se_tpg)
		goto out;
	rc = target_check_scsi2_reservation_conflict(cmd);
	if (rc == 1)
		goto out;
	if (rc < 0)
		return TCM_RESERVATION_CONFLICT;

	spin_lock(&dev->dev_reservation_lock);
	if (!dev->reservation_holder || !sess)
		goto out_unlock;

	if (dev->reservation_holder->se_node_acl != sess->se_node_acl)
		goto out_unlock;

	if (dev->dev_res_bin_isid != sess->sess_bin_isid)
		goto out_unlock;

	target_release_reservation(dev);
	tpg = sess->se_tpg;
	pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->"
		" MAPPED LUN: %llu for %s\n",
		tpg->se_tpg_tfo->fabric_name,
		cmd->se_lun->unpacked_lun, cmd->orig_fe_lun,
		sess->se_node_acl->initiatorname);

out_unlock:
	spin_unlock(&dev->dev_reservation_lock);
out:
	target_complete_cmd(cmd, GOOD);
	return 0;
}

sense_reason_t
target_scsi2_reservation_reserve(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *sess = cmd->se_sess;
	struct se_portal_group *tpg;
	sense_reason_t ret = 0;
	int rc;

	if ((cmd->t_task_cdb[1] & 0x01) &&
	    (cmd->t_task_cdb[1] & 0x02)) {
		pr_err("LongIO and Obsolete Bits set, returning ILLEGAL_REQUEST\n");
		return TCM_UNSUPPORTED_SCSI_OPCODE;
	}
	/*
	 * This is currently the case for target_core_mod passthrough struct se_cmd
	 * ops
	 */
	if (!sess || !sess->se_tpg)
		goto out;
	rc = target_check_scsi2_reservation_conflict(cmd);
	if (rc == 1)
		goto out;

	if (rc < 0)
		return TCM_RESERVATION_CONFLICT;

	tpg = sess->se_tpg;
	spin_lock(&dev->dev_reservation_lock);
	if (dev->reservation_holder &&
	    dev->reservation_holder->se_node_acl != sess->se_node_acl) {
		pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n",
			tpg->se_tpg_tfo->fabric_name);
		pr_err("Original reserver LUN: %llu %s\n",
			cmd->se_lun->unpacked_lun,
			dev->reservation_holder->se_node_acl->initiatorname);
		pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu"
			" from %s \n", cmd->se_lun->unpacked_lun,
			cmd->orig_fe_lun,
			sess->se_node_acl->initiatorname);
		ret = TCM_RESERVATION_CONFLICT;
		goto out_unlock;
	}

	dev->reservation_holder = sess;
	dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS;
	if (sess->sess_bin_isid != 0) {
		dev->dev_res_bin_isid = sess->sess_bin_isid;
		dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID;
	}
	pr_debug("SCSI-2 Reserved %s LUN: %llu -> MAPPED LUN: %llu"
		" for %s\n", tpg->se_tpg_tfo->fabric_name,
		cmd->se_lun->unpacked_lun, cmd->orig_fe_lun,
		sess->se_node_acl->initiatorname);

out_unlock:
	spin_unlock(&dev->dev_reservation_lock);
out:
	if (!ret)
		target_complete_cmd(cmd, GOOD);
	return ret;
}


/*
 * Begin SPC-3/SPC-4 Persistent Reservations emulation support
 *
 * This function is called by those initiator ports who are *NOT*
 * the active PR reservation holder when a reservation is present.
 */
static int core_scsi3_pr_seq_non_holder(struct se_cmd *cmd, u32 pr_reg_type,
					bool isid_mismatch)
{
	unsigned char *cdb = cmd->t_task_cdb;
	struct se_session *se_sess = cmd->se_sess;
	struct se_node_acl *nacl = se_sess->se_node_acl;
	int other_cdb = 0;
	int registered_nexus = 0, ret = 1; /* Conflict by default */
	int all_reg = 0, reg_only = 0; /* ALL_REG, REG_ONLY */
	int we = 0; /* Write Exclusive */
	int legacy = 0; /* Act like a legacy device and return
			 * RESERVATION CONFLICT on some CDBs */

	if (isid_mismatch) {
		registered_nexus = 0;
	} else {
		struct se_dev_entry *se_deve;

		rcu_read_lock();
		se_deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun);
		if (se_deve)
			registered_nexus = test_bit(DEF_PR_REG_ACTIVE,
						    &se_deve->deve_flags);
		rcu_read_unlock();
	}

	switch (pr_reg_type) {
	case PR_TYPE_WRITE_EXCLUSIVE:
		we = 1;
	case PR_TYPE_EXCLUSIVE_ACCESS:
		/*
		 * Some commands are only allowed for the persistent reservation
		 * holder.
		 */
		break;
	case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
		we = 1;
		/* fall through */
	case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
		/*
		 * Some commands are only allowed for registered I_T Nexuses.
		 */
		reg_only = 1;
		break;
	case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
		we = 1;
		/* fall through */
	case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
		/*
		 * Each registered I_T Nexus is a reservation holder.
		 */
		all_reg = 1;
		break;
	default:
		return -EINVAL;
	}
	/*
	 * Referenced from spc4r17 table 45 for *NON* PR holder access
	 */
	switch (cdb[0]) {
	case SECURITY_PROTOCOL_IN:
		if (registered_nexus)
			return 0;
		ret = (we) ? 0 : 1;
		break;
	case MODE_SENSE:
	case MODE_SENSE_10:
	case READ_ATTRIBUTE:
	case READ_BUFFER:
	case RECEIVE_DIAGNOSTIC:
		if (legacy) {
			ret = 1;
			break;
		}
		if (registered_nexus) {
			ret = 0;
			break;
		}
		ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
		break;
	case PERSISTENT_RESERVE_OUT:
		/*
		 * This follows PERSISTENT_RESERVE_OUT service actions that
		 * are allowed in the presence of various reservations.
		 * See spc4r17, table 46
		 */
		switch (cdb[1] & 0x1f) {
		case PRO_CLEAR:
		case PRO_PREEMPT:
		case PRO_PREEMPT_AND_ABORT:
			ret = (registered_nexus) ? 0 : 1;
			break;
		case PRO_REGISTER:
		case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
			ret = 0;
			break;
		case PRO_REGISTER_AND_MOVE:
		case PRO_RESERVE:
			ret = 1;
			break;
		case PRO_RELEASE:
			ret = (registered_nexus) ? 0 : 1;
			break;
		default:
			pr_err("Unknown PERSISTENT_RESERVE_OUT service"
				" action: 0x%02x\n", cdb[1] & 0x1f);
			return -EINVAL;
		}
		break;
	case RELEASE:
	case RELEASE_10:
		/* Handled by CRH=1 in target_scsi2_reservation_release() */
		ret = 0;
		break;
	case RESERVE:
	case RESERVE_10:
		/* Handled by CRH=1 in target_scsi2_reservation_reserve() */
		ret = 0;
		break;
	case TEST_UNIT_READY:
		ret = (legacy) ? 1 : 0; /* Conflict for legacy */
		break;
	case MAINTENANCE_IN:
		switch (cdb[1] & 0x1f) {
		case MI_MANAGEMENT_PROTOCOL_IN:
			if (registered_nexus) {
				ret = 0;
				break;
			}
			ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
			break;
		case MI_REPORT_SUPPORTED_OPERATION_CODES:
		case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS:
			if (legacy) {
				ret = 1;
				break;
			}
			if (registered_nexus) {
				ret = 0;
				break;
			}
			ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
			break;
		case MI_REPORT_ALIASES:
		case MI_REPORT_IDENTIFYING_INFORMATION:
		case MI_REPORT_PRIORITY:
		case MI_REPORT_TARGET_PGS:
		case MI_REPORT_TIMESTAMP:
			ret = 0; /* Allowed */
			break;
		default:
			pr_err("Unknown MI Service Action: 0x%02x\n",
				(cdb[1] & 0x1f));
			return -EINVAL;
		}
		break;
	case ACCESS_CONTROL_IN:
	case ACCESS_CONTROL_OUT:
	case INQUIRY:
	case LOG_SENSE:
	case SERVICE_ACTION_IN_12:
	case REPORT_LUNS:
	case REQUEST_SENSE:
	case PERSISTENT_RESERVE_IN:
		ret = 0; /*/ Allowed CDBs */
		break;
	default:
		other_cdb = 1;
		break;
	}
	/*
	 * Case where the CDB is explicitly allowed in the above switch
	 * statement.
	 */
	if (!ret && !other_cdb) {
		pr_debug("Allowing explicit CDB: 0x%02x for %s"
			" reservation holder\n", cdb[0],
			core_scsi3_pr_dump_type(pr_reg_type));

		return ret;
	}
	/*
	 * Check if write exclusive initiator ports *NOT* holding the
	 * WRITE_EXCLUSIVE_* reservation.
	 */
	if (we && !registered_nexus) {
		if (cmd->data_direction == DMA_TO_DEVICE) {
			/*
			 * Conflict for write exclusive
			 */
			pr_debug("%s Conflict for unregistered nexus"
				" %s CDB: 0x%02x to %s reservation\n",
				transport_dump_cmd_direction(cmd),
				se_sess->se_node_acl->initiatorname, cdb[0],
				core_scsi3_pr_dump_type(pr_reg_type));
			return 1;
		} else {
			/*
			 * Allow non WRITE CDBs for all Write Exclusive
			 * PR TYPEs to pass for registered and
			 * non-registered_nexuxes NOT holding the reservation.
			 *
			 * We only make noise for the unregisterd nexuses,
			 * as we expect registered non-reservation holding
			 * nexuses to issue CDBs.
			 */

			if (!registered_nexus) {
				pr_debug("Allowing implicit CDB: 0x%02x"
					" for %s reservation on unregistered"
					" nexus\n", cdb[0],
					core_scsi3_pr_dump_type(pr_reg_type));
			}

			return 0;
		}
	} else if ((reg_only) || (all_reg)) {
		if (registered_nexus) {
			/*
			 * For PR_*_REG_ONLY and PR_*_ALL_REG reservations,
			 * allow commands from registered nexuses.
			 */

			pr_debug("Allowing implicit CDB: 0x%02x for %s"
				" reservation\n", cdb[0],
				core_scsi3_pr_dump_type(pr_reg_type));

			return 0;
		}
       } else if (we && registered_nexus) {
               /*
                * Reads are allowed for Write Exclusive locks
                * from all registrants.
                */
               if (cmd->data_direction == DMA_FROM_DEVICE) {
                       pr_debug("Allowing READ CDB: 0x%02x for %s"
                               " reservation\n", cdb[0],
                               core_scsi3_pr_dump_type(pr_reg_type));

                       return 0;
               }
	}
	pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x"
		" for %s reservation\n", transport_dump_cmd_direction(cmd),
		(registered_nexus) ? "" : "un",
		se_sess->se_node_acl->initiatorname, cdb[0],
		core_scsi3_pr_dump_type(pr_reg_type));

	return 1; /* Conflict by default */
}

static sense_reason_t
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;
	bool isid_mismatch = false;

	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) {
			isid_mismatch = true;
			goto check_nonholder;
		}
	}

	return 0;

check_nonholder:
	if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type, isid_mismatch))
		return TCM_RESERVATION_CONFLICT;
	return 0;
}

static u32 core_scsi3_pr_generation(struct se_device *dev)
{
	u32 prg;

	/*
	 * PRGeneration field shall contain the value of a 32-bit wrapping
	 * counter mainted by the device server.
	 *
	 * Note that this is done regardless of Active Persist across
	 * Target PowerLoss (APTPL)
	 *
	 * See spc4r17 section 6.3.12 READ_KEYS service action
	 */
	spin_lock(&dev->dev_reservation_lock);
	prg = dev->t10_pr.pr_generation++;
	spin_unlock(&dev->dev_reservation_lock);

	return prg;
}

static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct se_lun *lun,
	struct se_dev_entry *dest_deve,
	u64 mapped_lun,
	unsigned char *isid,
	u64 sa_res_key,
	int all_tg_pt,
	int aptpl)
{
	struct t10_pr_registration *pr_reg;

	pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_ATOMIC);
	if (!pr_reg) {
		pr_err("Unable to allocate struct t10_pr_registration\n");
		return NULL;
	}

	INIT_LIST_HEAD(&pr_reg->pr_reg_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
	atomic_set(&pr_reg->pr_res_holders, 0);
	pr_reg->pr_reg_nacl = nacl;
	/*
	 * For destination registrations for ALL_TG_PT=1 and SPEC_I_PT=1,
	 * the se_dev_entry->pr_ref will have been already obtained by
	 * core_get_se_deve_from_rtpi() or __core_scsi3_alloc_registration().
	 *
	 * Otherwise, locate se_dev_entry now and obtain a reference until
	 * registration completes in __core_scsi3_add_registration().
	 */
	if (dest_deve) {
		pr_reg->pr_reg_deve = dest_deve;
	} else {
		rcu_read_lock();
		pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun);
		if (!pr_reg->pr_reg_deve) {
			rcu_read_unlock();
			pr_err("Unable to locate PR deve %s mapped_lun: %llu\n",
				nacl->initiatorname, mapped_lun);
			kmem_cache_free(t10_pr_reg_cache, pr_reg);
			return NULL;
		}
		kref_get(&pr_reg->pr_reg_deve->pr_kref);
		rcu_read_unlock();
	}
	pr_reg->pr_res_mapped_lun = mapped_lun;
	pr_reg->pr_aptpl_target_lun = lun->unpacked_lun;
	pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi;
	pr_reg->pr_res_key = sa_res_key;
	pr_reg->pr_reg_all_tg_pt = all_tg_pt;
	pr_reg->pr_reg_aptpl = aptpl;
	/*
	 * If an ISID value for this SCSI Initiator Port exists,
	 * save it to the registration now.
	 */
	if (isid != NULL) {
		pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
		snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
		pr_reg->isid_present_at_reg = 1;
	}

	return pr_reg;
}

static int core_scsi3_lunacl_depend_item(struct se_dev_entry *);
static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *);

/*
 * Function used for handling PR registrations for ALL_TG_PT=1 and ALL_TG_PT=0
 * modes.
 */
static struct t10_pr_registration *__core_scsi3_alloc_registration(
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct se_lun *lun,
	struct se_dev_entry *deve,
	u64 mapped_lun,
	unsigned char *isid,
	u64 sa_res_key,
	int all_tg_pt,
	int aptpl)
{
	struct se_dev_entry *deve_tmp;
	struct se_node_acl *nacl_tmp;
	struct se_lun_acl *lacl_tmp;
	struct se_lun *lun_tmp, *next, *dest_lun;
	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
	struct t10_pr_registration *pr_reg, *pr_reg_atp, *pr_reg_tmp, *pr_reg_tmp_safe;
	int ret;
	/*
	 * Create a registration for the I_T Nexus upon which the
	 * PROUT REGISTER was received.
	 */
	pr_reg = __core_scsi3_do_alloc_registration(dev, nacl, lun, deve, mapped_lun,
						    isid, sa_res_key, all_tg_pt,
						    aptpl);
	if (!pr_reg)
		return NULL;
	/*
	 * Return pointer to pr_reg for ALL_TG_PT=0
	 */
	if (!all_tg_pt)
		return pr_reg;
	/*
	 * Create list of matching SCSI Initiator Port registrations
	 * for ALL_TG_PT=1
	 */
	spin_lock(&dev->se_port_lock);
	list_for_each_entry_safe(lun_tmp, next, &dev->dev_sep_list, lun_dev_link) {
		if (!percpu_ref_tryget_live(&lun_tmp->lun_ref))
			continue;
		spin_unlock(&dev->se_port_lock);

		spin_lock(&lun_tmp->lun_deve_lock);
		list_for_each_entry(deve_tmp, &lun_tmp->lun_deve_list, lun_link) {
			/*
			 * This pointer will be NULL for demo mode MappedLUNs
			 * that have not been make explicit via a ConfigFS
			 * MappedLUN group for the SCSI Initiator Node ACL.
			 */
			if (!deve_tmp->se_lun_acl)
				continue;

			lacl_tmp = rcu_dereference_check(deve_tmp->se_lun_acl,
						lockdep_is_held(&lun_tmp->lun_deve_lock));
			nacl_tmp = lacl_tmp->se_lun_nacl;
			/*
			 * Skip the matching struct se_node_acl that is allocated
			 * above..
			 */
			if (nacl == nacl_tmp)
				continue;
			/*
			 * Only perform PR registrations for target ports on
			 * the same fabric module as the REGISTER w/ ALL_TG_PT=1
			 * arrived.
			 */
			if (tfo != nacl_tmp->se_tpg->se_tpg_tfo)
				continue;
			/*
			 * Look for a matching Initiator Node ACL in ASCII format
			 */
			if (strcmp(nacl->initiatorname, nacl_tmp->initiatorname))
				continue;

			kref_get(&deve_tmp->pr_kref);
			spin_unlock(&lun_tmp->lun_deve_lock);
			/*
			 * Grab a configfs group dependency that is released
			 * for the exception path at label out: below, or upon
			 * completion of adding ALL_TG_PT=1 registrations in
			 * __core_scsi3_add_registration()
			 */
			ret = core_scsi3_lunacl_depend_item(deve_tmp);
			if (ret < 0) {
				pr_err("core_scsi3_lunacl_depend"
						"_item() failed\n");
				percpu_ref_put(&lun_tmp->lun_ref);
				kref_put(&deve_tmp->pr_kref, target_pr_kref_release);
				goto out;
			}
			/*
			 * Located a matching SCSI Initiator Port on a different
			 * port, allocate the pr_reg_atp and attach it to the
			 * pr_reg->pr_reg_atp_list that will be processed once
			 * the original *pr_reg is processed in
			 * __core_scsi3_add_registration()
			 */
			dest_lun = rcu_dereference_check(deve_tmp->se_lun,
				kref_read(&deve_tmp->pr_kref) != 0);

			pr_reg_atp = __core_scsi3_do_alloc_registration(dev,
						nacl_tmp, dest_lun, deve_tmp,
						deve_tmp->mapped_lun, NULL,
						sa_res_key, all_tg_pt, aptpl);
			if (!pr_reg_atp) {
				percpu_ref_put(&lun_tmp->lun_ref);
				core_scsi3_lunacl_undepend_item(deve_tmp);
				goto out;
			}

			list_add_tail(&pr_reg_atp->pr_reg_atp_mem_list,
				      &pr_reg->pr_reg_atp_list);
			spin_lock(&lun_tmp->lun_deve_lock);
		}
		spin_unlock(&lun_tmp->lun_deve_lock);

		spin_lock(&dev->se_port_lock);
		percpu_ref_put(&lun_tmp->lun_ref);
	}
	spin_unlock(&dev->se_port_lock);

	return pr_reg;
out:
	list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
			&pr_reg->pr_reg_atp_list, pr_reg_atp_mem_list) {
		list_del(&pr_reg_tmp->pr_reg_atp_mem_list);
		core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve);
		kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp);
	}
	kmem_cache_free(t10_pr_reg_cache, pr_reg);
	return NULL;
}

int core_scsi3_alloc_aptpl_registration(
	struct t10_reservation *pr_tmpl,
	u64 sa_res_key,
	unsigned char *i_port,
	unsigned char *isid,
	u64 mapped_lun,
	unsigned char *t_port,
	u16 tpgt,
	u64 target_lun,
	int res_holder,
	int all_tg_pt,
	u8 type)
{
	struct t10_pr_registration *pr_reg;

	if (!i_port || !t_port || !sa_res_key) {
		pr_err("Illegal parameters for APTPL registration\n");
		return -EINVAL;
	}

	pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_KERNEL);
	if (!pr_reg) {
		pr_err("Unable to allocate struct t10_pr_registration\n");
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&pr_reg->pr_reg_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
	atomic_set(&pr_reg->pr_res_holders, 0);
	pr_reg->pr_reg_nacl = NULL;
	pr_reg->pr_reg_deve = NULL;
	pr_reg->pr_res_mapped_lun = mapped_lun;
	pr_reg->pr_aptpl_target_lun = target_lun;
	pr_reg->pr_res_key = sa_res_key;
	pr_reg->pr_reg_all_tg_pt = all_tg_pt;
	pr_reg->pr_reg_aptpl = 1;
	pr_reg->pr_res_scope = 0; /* Always LUN_SCOPE */
	pr_reg->pr_res_type = type;
	/*
	 * If an ISID value had been saved in APTPL metadata for this
	 * SCSI Initiator Port, restore it now.
	 */
	if (isid != NULL) {
		pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
		snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
		pr_reg->isid_present_at_reg = 1;
	}
	/*
	 * Copy the i_port and t_port information from caller.
	 */
	snprintf(pr_reg->pr_iport, PR_APTPL_MAX_IPORT_LEN, "%s", i_port);
	snprintf(pr_reg->pr_tport, PR_APTPL_MAX_TPORT_LEN, "%s", t_port);
	pr_reg->pr_reg_tpgt = tpgt;
	/*
	 * Set pr_res_holder from caller, the pr_reg who is the reservation
	 * holder will get it's pointer set in core_scsi3_aptpl_reserve() once
	 * the Initiator Node LUN ACL from the fabric module is created for
	 * this registration.
	 */
	pr_reg->pr_res_holder = res_holder;

	list_add_tail(&pr_reg->pr_reg_aptpl_list, &pr_tmpl->aptpl_reg_list);
	pr_debug("SPC-3 PR APTPL Successfully added registration%s from"
			" metadata\n", (res_holder) ? "+reservation" : "");
	return 0;
}

static void core_scsi3_aptpl_reserve(
	struct se_device *dev,
	struct se_portal_group *tpg,
	struct se_node_acl *node_acl,
	struct t10_pr_registration *pr_reg)
{
	char i_buf[PR_REG_ISID_ID_LEN];

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);

	spin_lock(&dev->dev_reservation_lock);
	dev->dev_pr_res_holder = pr_reg;
	spin_unlock(&dev->dev_reservation_lock);

	pr_debug("SPC-3 PR [%s] Service Action: APTPL RESERVE created"
		" new reservation holder TYPE: %s ALL_TG_PT: %d\n",
		tpg->se_tpg_tfo->fabric_name,
		core_scsi3_pr_dump_type(pr_reg->pr_res_type),
		(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
	pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n",
		tpg->se_tpg_tfo->fabric_name, node_acl->initiatorname,
		i_buf);
}

static void __core_scsi3_add_registration(struct se_device *, struct se_node_acl *,
				struct t10_pr_registration *, enum register_type, int);

static int __core_scsi3_check_aptpl_registration(
	struct se_device *dev,
	struct se_portal_group *tpg,
	struct se_lun *lun,
	u64 target_lun,
	struct se_node_acl *nacl,
	u64 mapped_lun)
{
	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char i_port[PR_APTPL_MAX_IPORT_LEN];
	unsigned char t_port[PR_APTPL_MAX_TPORT_LEN];
	u16 tpgt;

	memset(i_port, 0, PR_APTPL_MAX_IPORT_LEN);
	memset(t_port, 0, PR_APTPL_MAX_TPORT_LEN);
	/*
	 * Copy Initiator Port information from struct se_node_acl
	 */
	snprintf(i_port, PR_APTPL_MAX_IPORT_LEN, "%s", nacl->initiatorname);
	snprintf(t_port, PR_APTPL_MAX_TPORT_LEN, "%s",
			tpg->se_tpg_tfo->tpg_get_wwn(tpg));
	tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg);
	/*
	 * Look for the matching registrations+reservation from those
	 * created from APTPL metadata.  Note that multiple registrations
	 * may exist for fabrics that use ISIDs in their SCSI Initiator Port
	 * TransportIDs.
	 */
	spin_lock(&pr_tmpl->aptpl_reg_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list,
				pr_reg_aptpl_list) {

		if (!strcmp(pr_reg->pr_iport, i_port) &&
		     (pr_reg->pr_res_mapped_lun == mapped_lun) &&
		    !(strcmp(pr_reg->pr_tport, t_port)) &&
		     (pr_reg->pr_reg_tpgt == tpgt) &&
		     (pr_reg->pr_aptpl_target_lun == target_lun)) {
			/*
			 * Obtain the ->pr_reg_deve pointer + reference, that
			 * is released by __core_scsi3_add_registration() below.
			 */
			rcu_read_lock();
			pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun);
			if (!pr_reg->pr_reg_deve) {
				pr_err("Unable to locate PR APTPL %s mapped_lun:"
					" %llu\n", nacl->initiatorname, mapped_lun);
				rcu_read_unlock();
				continue;
			}
			kref_get(&pr_reg->pr_reg_deve->pr_kref);
			rcu_read_unlock();

			pr_reg->pr_reg_nacl = nacl;
			pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi;
			list_del(&pr_reg->pr_reg_aptpl_list);
			spin_unlock(&pr_tmpl->aptpl_reg_lock);
			/*
			 * At this point all of the pointers in *pr_reg will
			 * be setup, so go ahead and add the registration.
			 */
			__core_scsi3_add_registration(dev, nacl, pr_reg, 0, 0);
			/*
			 * If this registration is the reservation holder,
			 * make that happen now..
			 */
			if (pr_reg->pr_res_holder)
				core_scsi3_aptpl_reserve(dev, tpg,
						nacl, pr_reg);
			/*
			 * Reenable pr_aptpl_active to accept new metadata
			 * updates once the SCSI device is active again..
			 */
			spin_lock(&pr_tmpl->aptpl_reg_lock);
			pr_tmpl->pr_aptpl_active = 1;
		}
	}
	spin_unlock(&pr_tmpl->aptpl_reg_lock);

	return 0;
}

int core_scsi3_check_aptpl_registration(
	struct se_device *dev,
	struct se_portal_group *tpg,
	struct se_lun *lun,
	struct se_node_acl *nacl,
	u64 mapped_lun)
{
	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
		return 0;

	return __core_scsi3_check_aptpl_registration(dev, tpg, lun,
						     lun->unpacked_lun, nacl,
						     mapped_lun);
}

static void __core_scsi3_dump_registration(
	const struct target_core_fabric_ops *tfo,
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct t10_pr_registration *pr_reg,
	enum register_type register_type)
{
	struct se_portal_group *se_tpg = nacl->se_tpg;
	char i_buf[PR_REG_ISID_ID_LEN];

	memset(&i_buf[0], 0, PR_REG_ISID_ID_LEN);
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);

	pr_debug("SPC-3 PR [%s] Service Action: REGISTER%s Initiator"
		" Node: %s%s\n", tfo->fabric_name, (register_type == REGISTER_AND_MOVE) ?
		"_AND_MOVE" : (register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ?
		"_AND_IGNORE_EXISTING_KEY" : "", nacl->initiatorname,
		i_buf);
	pr_debug("SPC-3 PR [%s] registration on Target Port: %s,0x%04x\n",
		 tfo->fabric_name, tfo->tpg_get_wwn(se_tpg),
		tfo->tpg_get_tag(se_tpg));
	pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target"
		" Port(s)\n",  tfo->fabric_name,
		(pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE",
		dev->transport->name);
	pr_debug("SPC-3 PR [%s] SA Res Key: 0x%016Lx PRgeneration:"
		" 0x%08x  APTPL: %d\n", tfo->fabric_name,
		pr_reg->pr_res_key, pr_reg->pr_res_generation,
		pr_reg->pr_reg_aptpl);
}

static void __core_scsi3_add_registration(
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct t10_pr_registration *pr_reg,
	enum register_type register_type,
	int register_move)
{
	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct se_dev_entry *deve;

	/*
	 * Increment PRgeneration counter for struct se_device upon a successful
	 * REGISTER, see spc4r17 section 6.3.2 READ_KEYS service action
	 *
	 * Also, when register_move = 1 for PROUT REGISTER_AND_MOVE service
	 * action, the struct se_device->dev_reservation_lock will already be held,
	 * so we do not call core_scsi3_pr_generation() which grabs the lock
	 * for the REGISTER.
	 */
	pr_reg->pr_res_generation = (register_move) ?
			dev->t10_pr.pr_generation++ :
			core_scsi3_pr_generation(dev);

	spin_lock(&pr_tmpl->registration_lock);
	list_add_tail(&pr_reg->pr_reg_list, &pr_tmpl->registration_list);

	__core_scsi3_dump_registration(tfo, dev, nacl, pr_reg, register_type);
	spin_unlock(&pr_tmpl->registration_lock);
	/*
	 * Skip extra processing for ALL_TG_PT=0 or REGISTER_AND_MOVE.
	 */
	if (!pr_reg->pr_reg_all_tg_pt || register_move)
		goto out;
	/*
	 * Walk pr_reg->pr_reg_atp_list and add registrations for ALL_TG_PT=1
	 * allocated in __core_scsi3_alloc_registration()
	 */
	list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
			&pr_reg->pr_reg_atp_list, pr_reg_atp_mem_list) {
		struct se_node_acl *nacl_tmp = pr_reg_tmp->pr_reg_nacl;

		list_del(&pr_reg_tmp->pr_reg_atp_mem_list);

		pr_reg_tmp->pr_res_generation = core_scsi3_pr_generation(dev);

		spin_lock(&pr_tmpl->registration_lock);
		list_add_tail(&pr_reg_tmp->pr_reg_list,
			      &pr_tmpl->registration_list);

		__core_scsi3_dump_registration(tfo, dev, nacl_tmp, pr_reg_tmp,
					       register_type);
		spin_unlock(&pr_tmpl->registration_lock);
		/*
		 * Drop configfs group dependency reference and deve->pr_kref
		 * obtained from  __core_scsi3_alloc_registration() code.
		 */
		rcu_read_lock();
		deve = pr_reg_tmp->pr_reg_deve;
		if (deve) {
			set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags);
			core_scsi3_lunacl_undepend_item(deve);
			pr_reg_tmp->pr_reg_deve = NULL;
		}
		rcu_read_unlock();
	}
out:
	/*
	 * Drop deve->pr_kref obtained in __core_scsi3_do_alloc_registration()
	 */
	rcu_read_lock();
	deve = pr_reg->pr_reg_deve;
	if (deve) {
		set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags);
		kref_put(&deve->pr_kref, target_pr_kref_release);
		pr_reg->pr_reg_deve = NULL;
	}
	rcu_read_unlock();
}

static int core_scsi3_alloc_registration(
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct se_lun *lun,
	struct se_dev_entry *deve,
	u64 mapped_lun,
	unsigned char *isid,
	u64 sa_res_key,
	int all_tg_pt,
	int aptpl,
	enum register_type register_type,
	int register_move)
{
	struct t10_pr_registration *pr_reg;

	pr_reg = __core_scsi3_alloc_registration(dev, nacl, lun, deve, mapped_lun,
						 isid, sa_res_key, all_tg_pt,
						 aptpl);
	if (!pr_reg)
		return -EPERM;

	__core_scsi3_add_registration(dev, nacl, pr_reg,
			register_type, register_move);
	return 0;
}

static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
	struct se_device *dev,
	struct se_node_acl *nacl,
	unsigned char *isid)
{
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
	struct se_portal_group *tpg;

	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {
		/*
		 * First look for a matching struct se_node_acl
		 */
		if (pr_reg->pr_reg_nacl != nacl)
			continue;

		tpg = pr_reg->pr_reg_nacl->se_tpg;
		/*
		 * If this registration does NOT contain a fabric provided
		 * ISID, then we have found a match.
		 */
		if (!pr_reg->isid_present_at_reg) {
			/*
			 * Determine if this SCSI device server requires that
			 * SCSI Intiatior TransportID w/ ISIDs is enforced
			 * for fabric modules (iSCSI) requiring them.
			 */
			if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
				if (dev->dev_attrib.enforce_pr_isids)
					continue;
			}
			atomic_inc_mb(&pr_reg->pr_res_holders);
			spin_unlock(&pr_tmpl->registration_lock);
			return pr_reg;
		}
		/*
		 * If the *pr_reg contains a fabric defined ISID for multi-value
		 * SCSI Initiator Port TransportIDs, then we expect a valid
		 * matching ISID to be provided by the local SCSI Initiator Port.
		 */
		if (!isid)
			continue;
		if (strcmp(isid, pr_reg->pr_reg_isid))
			continue;

		atomic_inc_mb(&pr_reg->pr_res_holders);
		spin_unlock(&pr_tmpl->registration_lock);
		return pr_reg;
	}
	spin_unlock(&pr_tmpl->registration_lock);

	return NULL;
}

static struct t10_pr_registration *core_scsi3_locate_pr_reg(
	struct se_device *dev,
	struct se_node_acl *nacl,
	struct se_session *sess)
{
	struct se_portal_group *tpg = nacl->se_tpg;
	unsigned char buf[PR_REG_ISID_LEN], *isid_ptr = NULL;

	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
		memset(&buf[0], 0, PR_REG_ISID_LEN);
		tpg->se_tpg_tfo->sess_get_initiator_sid(sess, &buf[0],
					PR_REG_ISID_LEN);
		isid_ptr = &buf[0];
	}

	return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr);
}

static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
{
	atomic_dec_mb(&pr_reg->pr_res_holders);
}

static int core_scsi3_check_implicit_release(
	struct se_device *dev,
	struct t10_pr_registration *pr_reg)
{
	struct se_node_acl *nacl = pr_reg->pr_reg_nacl;
	struct t10_pr_registration *pr_res_holder;
	int ret = 0;

	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (!pr_res_holder) {
		spin_unlock(&dev->dev_reservation_lock);
		return ret;
	}
	if (pr_res_holder == pr_reg) {
		/*
		 * Perform an implicit RELEASE if the registration that
		 * is being released is holding the reservation.
		 *
		 * From spc4r17, section 5.7.11.1:
		 *
		 * e) If the I_T nexus is the persistent reservation holder
		 *    and the persistent reservation is not an all registrants
		 *    type, then a PERSISTENT RESERVE OUT command with REGISTER
		 *    service action or REGISTER AND  IGNORE EXISTING KEY
		 *    service action with the SERVICE ACTION RESERVATION KEY
		 *    field set to zero (see 5.7.11.3).
		 */
		__core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0, 1);
		ret = 1;
		/*
		 * For 'All Registrants' reservation types, all existing
		 * registrations are still processed as reservation holders
		 * in core_scsi3_pr_seq_non_holder() after the initial
		 * reservation holder is implicitly released here.
		 */
	} else if (pr_reg->pr_reg_all_tg_pt &&
		  (!strcmp(pr_res_holder->pr_reg_nacl->initiatorname,
			  pr_reg->pr_reg_nacl->initiatorname)) &&
		  (pr_res_holder->pr_res_key == pr_reg->pr_res_key)) {
		pr_err("SPC-3 PR: Unable to perform ALL_TG_PT=1"
			" UNREGISTER while existing reservation with matching"
			" key 0x%016Lx is present from another SCSI Initiator"
			" Port\n", pr_reg->pr_res_key);
		ret = -EPERM;
	}
	spin_unlock(&dev->dev_reservation_lock);

	return ret;
}

static void __core_scsi3_free_registration(
	struct se_device *dev,
	struct t10_pr_registration *pr_reg,
	struct list_head *preempt_and_abort_list,
	int dec_holders)
	__releases(&pr_tmpl->registration_lock)
	__acquires(&pr_tmpl->registration_lock)
{
	const struct target_core_fabric_ops *tfo =
			pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct se_node_acl *nacl = pr_reg->pr_reg_nacl;
	struct se_dev_entry *deve;
	char i_buf[PR_REG_ISID_ID_LEN];

	lockdep_assert_held(&pr_tmpl->registration_lock);

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);

	if (!list_empty(&pr_reg->pr_reg_list))
		list_del(&pr_reg->pr_reg_list);
	/*
	 * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(),
	 * so call core_scsi3_put_pr_reg() to decrement our reference.
	 */
	if (dec_holders)
		core_scsi3_put_pr_reg(pr_reg);

	spin_unlock(&pr_tmpl->registration_lock);
	/*
	 * Wait until all reference from any other I_T nexuses for this
	 * *pr_reg have been released.  Because list_del() is called above,
	 * the last core_scsi3_put_pr_reg(pr_reg) will release this reference
	 * count back to zero, and we release *pr_reg.
	 */
	while (atomic_read(&pr_reg->pr_res_holders) != 0) {
		pr_debug("SPC-3 PR [%s] waiting for pr_res_holders\n",
				tfo->fabric_name);
		cpu_relax();
	}

	rcu_read_lock();
	deve = target_nacl_find_deve(nacl, pr_reg->pr_res_mapped_lun);
	if (deve)
		clear_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags);
	rcu_read_unlock();

	spin_lock(&pr_tmpl->registration_lock);
	pr_debug("SPC-3 PR [%s] Service Action: UNREGISTER Initiator"
		" Node: %s%s\n", tfo->fabric_name,
		pr_reg->pr_reg_nacl->initiatorname,
		i_buf);
	pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target"
		" Port(s)\n", tfo->fabric_name,
		(pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE",
		dev->transport->name);
	pr_debug("SPC-3 PR [%s] SA Res Key: 0x%016Lx PRgeneration:"
		" 0x%08x\n", tfo->fabric_name, pr_reg->pr_res_key,
		pr_reg->pr_res_generation);

	if (!preempt_and_abort_list) {
		pr_reg->pr_reg_deve = NULL;
		pr_reg->pr_reg_nacl = NULL;
		kmem_cache_free(t10_pr_reg_cache, pr_reg);
		return;
	}
	/*
	 * For PREEMPT_AND_ABORT, the list of *pr_reg in preempt_and_abort_list
	 * are released once the ABORT_TASK_SET has completed..
	 */
	list_add_tail(&pr_reg->pr_reg_abort_list, preempt_and_abort_list);
}

void core_scsi3_free_pr_reg_from_nacl(
	struct se_device *dev,
	struct se_node_acl *nacl)
{
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
	bool free_reg = false;
	/*
	 * If the passed se_node_acl matches the reservation holder,
	 * release the reservation.
	 */
	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if ((pr_res_holder != NULL) &&
	    (pr_res_holder->pr_reg_nacl == nacl)) {
		__core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0, 1);
		free_reg = true;
	}
	spin_unlock(&dev->dev_reservation_lock);
	/*
	 * Release any registration associated with the struct se_node_acl.
	 */
	spin_lock(&pr_tmpl->registration_lock);
	if (pr_res_holder && free_reg)
		__core_scsi3_free_registration(dev, pr_res_holder, NULL, 0);

	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {

		if (pr_reg->pr_reg_nacl != nacl)
			continue;

		__core_scsi3_free_registration(dev, pr_reg, NULL, 0);
	}
	spin_unlock(&pr_tmpl->registration_lock);
}

void core_scsi3_free_all_registrations(
	struct se_device *dev)
{
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;

	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (pr_res_holder != NULL) {
		struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
		__core_scsi3_complete_pro_release(dev, pr_res_nacl,
						  pr_res_holder, 0, 0);
	}
	spin_unlock(&dev->dev_reservation_lock);

	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {

		__core_scsi3_free_registration(dev, pr_reg, NULL, 0);
	}
	spin_unlock(&pr_tmpl->registration_lock);

	spin_lock(&pr_tmpl->aptpl_reg_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list,
				pr_reg_aptpl_list) {
		list_del(&pr_reg->pr_reg_aptpl_list);
		kmem_cache_free(t10_pr_reg_cache, pr_reg);
	}
	spin_unlock(&pr_tmpl->aptpl_reg_lock);
}

static int core_scsi3_tpg_depend_item(struct se_portal_group *tpg)
{
	return target_depend_item(&tpg->tpg_group.cg_item);
}

static void core_scsi3_tpg_undepend_item(struct se_portal_group *tpg)
{
	target_undepend_item(&tpg->tpg_group.cg_item);
	atomic_dec_mb(&tpg->tpg_pr_ref_count);
}

static int core_scsi3_nodeacl_depend_item(struct se_node_acl *nacl)
{
	if (nacl->dynamic_node_acl)
		return 0;
	return target_depend_item(&nacl->acl_group.cg_item);
}

static void core_scsi3_nodeacl_undepend_item(struct se_node_acl *nacl)
{
	if (!nacl->dynamic_node_acl)
		target_undepend_item(&nacl->acl_group.cg_item);
	atomic_dec_mb(&nacl->acl_pr_ref_count);
}

static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve)
{
	struct se_lun_acl *lun_acl;

	/*
	 * For nacl->dynamic_node_acl=1
	 */
	lun_acl = rcu_dereference_check(se_deve->se_lun_acl,
				kref_read(&se_deve->pr_kref) != 0);
	if (!lun_acl)
		return 0;

	return target_depend_item(&lun_acl->se_lun_group.cg_item);
}

static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
{
	struct se_lun_acl *lun_acl;

	/*
	 * For nacl->dynamic_node_acl=1
	 */
	lun_acl = rcu_dereference_check(se_deve->se_lun_acl,
				kref_read(&se_deve->pr_kref) != 0);
	if (!lun_acl) {
		kref_put(&se_deve->pr_kref, target_pr_kref_release);
		return;
	}

	target_undepend_item(&lun_acl->se_lun_group.cg_item);
	kref_put(&se_deve->pr_kref, target_pr_kref_release);
}

static sense_reason_t
core_scsi3_decode_spec_i_port(
	struct se_cmd *cmd,
	struct se_portal_group *tpg,
	unsigned char *l_isid,
	u64 sa_res_key,
	int all_tg_pt,
	int aptpl)
{
	struct se_device *dev = cmd->se_dev;
	struct se_portal_group *dest_tpg = NULL, *tmp_tpg;
	struct se_session *se_sess = cmd->se_sess;
	struct se_node_acl *dest_node_acl = NULL;
	struct se_dev_entry *dest_se_deve = NULL;
	struct t10_pr_registration *dest_pr_reg, *local_pr_reg, *pr_reg_e;
	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
	LIST_HEAD(tid_dest_list);
	struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
	unsigned char *buf, *ptr, proto_ident;
	const unsigned char *i_str = NULL;
	char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
	sense_reason_t ret;
	u32 tpdl, tid_len = 0;
	u32 dest_rtpi = 0;

	/*
	 * Allocate a struct pr_transport_id_holder and setup the
	 * local_node_acl pointer and add to struct list_head tid_dest_list
	 * for add registration processing in the loop of tid_dest_list below.
	 */
	tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL);
	if (!tidh_new) {
		pr_err("Unable to allocate tidh_new\n");
		return TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
	}
	INIT_LIST_HEAD(&tidh_new->dest_list);
	tidh_new->dest_tpg = tpg;
	tidh_new->dest_node_acl = se_sess->se_node_acl;

	local_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev,
				se_sess->se_node_acl, cmd->se_lun,
				NULL, cmd->orig_fe_lun, l_isid,
				sa_res_key, all_tg_pt, aptpl);
	if (!local_pr_reg) {
		kfree(tidh_new);
		return TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
	}
	tidh_new->dest_pr_reg = local_pr_reg;
	/*
	 * The local I_T nexus does not hold any configfs dependances,
	 * so we set tidh_new->dest_se_deve to NULL to prevent the
	 * configfs_undepend_item() calls in the tid_dest_list loops below.
	 */
	tidh_new->dest_se_deve = NULL;
	list_add_tail(&tidh_new->dest_list, &tid_dest_list);

	if (cmd->data_length < 28) {
		pr_warn("SPC-PR: Received PR OUT parameter list"
			" length too small: %u\n", cmd->data_length);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf) {
		ret = TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
		goto out;
	}

	/*
	 * For a PERSISTENT RESERVE OUT specify initiator ports payload,
	 * first extract TransportID Parameter Data Length, and make sure
	 * the value matches up to the SCSI expected data transfer length.
	 */
	tpdl = get_unaligned_be32(&buf[24]);

	if ((tpdl + 28) != cmd->data_length) {
		pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header"
			" does not equal CDB data_length: %u\n", tpdl,
			cmd->data_length);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out_unmap;
	}
	/*
	 * Start processing the received transport IDs using the
	 * receiving I_T Nexus portal's fabric dependent methods to
	 * obtain the SCSI Initiator Port/Device Identifiers.
	 */
	ptr = &buf[28];

	while (tpdl > 0) {
		struct se_lun *dest_lun, *tmp_lun;

		proto_ident = (ptr[0] & 0x0f);
		dest_tpg = NULL;

		spin_lock(&dev->se_port_lock);
		list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) {
			tmp_tpg = tmp_lun->lun_tpg;

			/*
			 * Look for the matching proto_ident provided by
			 * the received TransportID
			 */
			if (tmp_tpg->proto_id != proto_ident)
				continue;
			dest_rtpi = tmp_lun->lun_rtpi;

			i_str = target_parse_pr_out_transport_id(tmp_tpg,
					ptr, &tid_len, &iport_ptr);
			if (!i_str)
				continue;

			atomic_inc_mb(&tmp_tpg->tpg_pr_ref_count);
			spin_unlock(&dev->se_port_lock);

			if (core_scsi3_tpg_depend_item(tmp_tpg)) {
				pr_err(" core_scsi3_tpg_depend_item()"
					" for tmp_tpg\n");
				atomic_dec_mb(&tmp_tpg->tpg_pr_ref_count);
				ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
				goto out_unmap;
			}
			/*
			 * Locate the destination initiator ACL to be registered
			 * from the decoded fabric module specific TransportID
			 * at *i_str.
			 */
			mutex_lock(&tmp_tpg->acl_node_mutex);
			dest_node_acl = __core_tpg_get_initiator_node_acl(
						tmp_tpg, i_str);
			if (dest_node_acl)
				atomic_inc_mb(&dest_node_acl->acl_pr_ref_count);
			mutex_unlock(&tmp_tpg->acl_node_mutex);

			if (!dest_node_acl) {
				core_scsi3_tpg_undepend_item(tmp_tpg);
				spin_lock(&dev->se_port_lock);
				continue;
			}

			if (core_scsi3_nodeacl_depend_item(dest_node_acl)) {
				pr_err("configfs_depend_item() failed"
					" for dest_node_acl->acl_group\n");
				atomic_dec_mb(&dest_node_acl->acl_pr_ref_count);
				core_scsi3_tpg_undepend_item(tmp_tpg);
				ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
				goto out_unmap;
			}

			dest_tpg = tmp_tpg;
			pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node:"
				" %s Port RTPI: %hu\n",
				dest_tpg->se_tpg_tfo->fabric_name,
				dest_node_acl->initiatorname, dest_rtpi);

			spin_lock(&dev->se_port_lock);
			break;
		}
		spin_unlock(&dev->se_port_lock);

		if (!dest_tpg) {
			pr_err("SPC-3 PR SPEC_I_PT: Unable to locate"
					" dest_tpg\n");
			ret = TCM_INVALID_PARAMETER_LIST;
			goto out_unmap;
		}

		pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u"
			" tid_len: %d for %s + %s\n",
			dest_tpg->se_tpg_tfo->fabric_name, cmd->data_length,
			tpdl, tid_len, i_str, iport_ptr);

		if (tid_len > tpdl) {
			pr_err("SPC-3 PR SPEC_I_PT: Illegal tid_len:"
				" %u for Transport ID: %s\n", tid_len, ptr);
			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			ret = TCM_INVALID_PARAMETER_LIST;
			goto out_unmap;
		}
		/*
		 * Locate the desintation struct se_dev_entry pointer for matching
		 * RELATIVE TARGET PORT IDENTIFIER on the receiving I_T Nexus
		 * Target Port.
		 */
		dest_se_deve = core_get_se_deve_from_rtpi(dest_node_acl,
					dest_rtpi);
		if (!dest_se_deve) {
			pr_err("Unable to locate %s dest_se_deve"
				" from destination RTPI: %hu\n",
				dest_tpg->se_tpg_tfo->fabric_name,
				dest_rtpi);

			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			ret = TCM_INVALID_PARAMETER_LIST;
			goto out_unmap;
		}

		if (core_scsi3_lunacl_depend_item(dest_se_deve)) {
			pr_err("core_scsi3_lunacl_depend_item()"
					" failed\n");
			kref_put(&dest_se_deve->pr_kref, target_pr_kref_release);
			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
			goto out_unmap;
		}

		pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s"
			" dest_se_deve mapped_lun: %llu\n",
			dest_tpg->se_tpg_tfo->fabric_name,
			dest_node_acl->initiatorname, dest_se_deve->mapped_lun);

		/*
		 * Skip any TransportIDs that already have a registration for
		 * this target port.
		 */
		pr_reg_e = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
					iport_ptr);
		if (pr_reg_e) {
			core_scsi3_put_pr_reg(pr_reg_e);
			core_scsi3_lunacl_undepend_item(dest_se_deve);
			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			ptr += tid_len;
			tpdl -= tid_len;
			tid_len = 0;
			continue;
		}
		/*
		 * Allocate a struct pr_transport_id_holder and setup
		 * the dest_node_acl and dest_se_deve pointers for the
		 * loop below.
		 */
		tidh_new = kzalloc(sizeof(struct pr_transport_id_holder),
				GFP_KERNEL);
		if (!tidh_new) {
			pr_err("Unable to allocate tidh_new\n");
			core_scsi3_lunacl_undepend_item(dest_se_deve);
			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
			goto out_unmap;
		}
		INIT_LIST_HEAD(&tidh_new->dest_list);
		tidh_new->dest_tpg = dest_tpg;
		tidh_new->dest_node_acl = dest_node_acl;
		tidh_new->dest_se_deve = dest_se_deve;

		/*
		 * Allocate, but do NOT add the registration for the
		 * TransportID referenced SCSI Initiator port.  This
		 * done because of the following from spc4r17 in section
		 * 6.14.3 wrt SPEC_I_PT:
		 *
		 * "If a registration fails for any initiator port (e.g., if th
		 * logical unit does not have enough resources available to
		 * hold the registration information), no registrations shall be
		 * made, and the command shall be terminated with
		 * CHECK CONDITION status."
		 *
		 * That means we call __core_scsi3_alloc_registration() here,
		 * and then call __core_scsi3_add_registration() in the
		 * 2nd loop which will never fail.
		 */
		dest_lun = rcu_dereference_check(dest_se_deve->se_lun,
				kref_read(&dest_se_deve->pr_kref) != 0);

		dest_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev,
					dest_node_acl, dest_lun, dest_se_deve,
					dest_se_deve->mapped_lun, iport_ptr,
					sa_res_key, all_tg_pt, aptpl);
		if (!dest_pr_reg) {
			core_scsi3_lunacl_undepend_item(dest_se_deve);
			core_scsi3_nodeacl_undepend_item(dest_node_acl);
			core_scsi3_tpg_undepend_item(dest_tpg);
			kfree(tidh_new);
			ret = TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
			goto out_unmap;
		}
		tidh_new->dest_pr_reg = dest_pr_reg;
		list_add_tail(&tidh_new->dest_list, &tid_dest_list);

		ptr += tid_len;
		tpdl -= tid_len;
		tid_len = 0;

	}

	transport_kunmap_data_sg(cmd);

	/*
	 * Go ahead and create a registrations from tid_dest_list for the
	 * SPEC_I_PT provided TransportID for the *tidh referenced dest_node_acl
	 * and dest_se_deve.
	 *
	 * The SA Reservation Key from the PROUT is set for the
	 * registration, and ALL_TG_PT is also passed.  ALL_TG_PT=1
	 * means that the TransportID Initiator port will be
	 * registered on all of the target ports in the SCSI target device
	 * ALL_TG_PT=0 means the registration will only be for the
	 * SCSI target port the PROUT REGISTER with SPEC_I_PT=1
	 * was received.
	 */
	list_for_each_entry_safe(tidh, tidh_tmp, &tid_dest_list, dest_list) {
		dest_tpg = tidh->dest_tpg;
		dest_node_acl = tidh->dest_node_acl;
		dest_se_deve = tidh->dest_se_deve;
		dest_pr_reg = tidh->dest_pr_reg;

		list_del(&tidh->dest_list);
		kfree(tidh);

		memset(i_buf, 0, PR_REG_ISID_ID_LEN);
		core_pr_dump_initiator_port(dest_pr_reg, i_buf, PR_REG_ISID_ID_LEN);

		__core_scsi3_add_registration(cmd->se_dev, dest_node_acl,
					dest_pr_reg, 0, 0);

		pr_debug("SPC-3 PR [%s] SPEC_I_PT: Successfully"
			" registered Transport ID for Node: %s%s Mapped LUN:"
			" %llu\n", dest_tpg->se_tpg_tfo->fabric_name,
			dest_node_acl->initiatorname, i_buf, (dest_se_deve) ?
			dest_se_deve->mapped_lun : 0);

		if (!dest_se_deve) {
			kref_put(&local_pr_reg->pr_reg_deve->pr_kref,
				 target_pr_kref_release);
			continue;
		}
		core_scsi3_lunacl_undepend_item(dest_se_deve);
		core_scsi3_nodeacl_undepend_item(dest_node_acl);
		core_scsi3_tpg_undepend_item(dest_tpg);
	}

	return 0;
out_unmap:
	transport_kunmap_data_sg(cmd);
out:
	/*
	 * For the failure case, release everything from tid_dest_list
	 * including *dest_pr_reg and the configfs dependances..
	 */
	list_for_each_entry_safe(tidh, tidh_tmp, &tid_dest_list, dest_list) {
		dest_tpg = tidh->dest_tpg;
		dest_node_acl = tidh->dest_node_acl;
		dest_se_deve = tidh->dest_se_deve;
		dest_pr_reg = tidh->dest_pr_reg;

		list_del(&tidh->dest_list);
		kfree(tidh);
		/*
		 * Release any extra ALL_TG_PT=1 registrations for
		 * the SPEC_I_PT=1 case.
		 */
		list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
				&dest_pr_reg->pr_reg_atp_list,
				pr_reg_atp_mem_list) {
			list_del(&pr_reg_tmp->pr_reg_atp_mem_list);
			core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve);
			kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp);
		}

		kmem_cache_free(t10_pr_reg_cache, dest_pr_reg);

		if (!dest_se_deve) {
			kref_put(&local_pr_reg->pr_reg_deve->pr_kref,
				 target_pr_kref_release);
			continue;
		}
		core_scsi3_lunacl_undepend_item(dest_se_deve);
		core_scsi3_nodeacl_undepend_item(dest_node_acl);
		core_scsi3_tpg_undepend_item(dest_tpg);
	}
	return ret;
}

static int core_scsi3_update_aptpl_buf(
	struct se_device *dev,
	unsigned char *buf,
	u32 pr_aptpl_buf_len)
{
	struct se_portal_group *tpg;
	struct t10_pr_registration *pr_reg;
	unsigned char tmp[512], isid_buf[32];
	ssize_t len = 0;
	int reg_count = 0;
	int ret = 0;

	spin_lock(&dev->dev_reservation_lock);
	spin_lock(&dev->t10_pr.registration_lock);
	/*
	 * Walk the registration list..
	 */
	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list,
			pr_reg_list) {

		tmp[0] = '\0';
		isid_buf[0] = '\0';
		tpg = pr_reg->pr_reg_nacl->se_tpg;
		/*
		 * Write out any ISID value to APTPL metadata that was included
		 * in the original registration.
		 */
		if (pr_reg->isid_present_at_reg)
			snprintf(isid_buf, 32, "initiator_sid=%s\n",
					pr_reg->pr_reg_isid);
		/*
		 * Include special metadata if the pr_reg matches the
		 * reservation holder.
		 */
		if (dev->dev_pr_res_holder == pr_reg) {
			snprintf(tmp, 512, "PR_REG_START: %d"
				"\ninitiator_fabric=%s\n"
				"initiator_node=%s\n%s"
				"sa_res_key=%llu\n"
				"res_holder=1\nres_type=%02x\n"
				"res_scope=%02x\nres_all_tg_pt=%d\n"
				"mapped_lun=%llu\n", reg_count,
				tpg->se_tpg_tfo->fabric_name,
				pr_reg->pr_reg_nacl->initiatorname, isid_buf,
				pr_reg->pr_res_key, pr_reg->pr_res_type,
				pr_reg->pr_res_scope, pr_reg->pr_reg_all_tg_pt,
				pr_reg->pr_res_mapped_lun);
		} else {
			snprintf(tmp, 512, "PR_REG_START: %d\n"
				"initiator_fabric=%s\ninitiator_node=%s\n%s"
				"sa_res_key=%llu\nres_holder=0\n"
				"res_all_tg_pt=%d\nmapped_lun=%llu\n",
				reg_count, tpg->se_tpg_tfo->fabric_name,
				pr_reg->pr_reg_nacl->initiatorname, isid_buf,
				pr_reg->pr_res_key, pr_reg->pr_reg_all_tg_pt,
				pr_reg->pr_res_mapped_lun);
		}

		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
			pr_err("Unable to update renaming APTPL metadata,"
			       " reallocating larger buffer\n");
			ret = -EMSGSIZE;
			goto out;
		}
		len += sprintf(buf+len, "%s", tmp);

		/*
		 * Include information about the associated SCSI target port.
		 */
		snprintf(tmp, 512, "target_fabric=%s\ntarget_node=%s\n"
			"tpgt=%hu\nport_rtpi=%hu\ntarget_lun=%llu\nPR_REG_END:"
			" %d\n", tpg->se_tpg_tfo->fabric_name,
			tpg->se_tpg_tfo->tpg_get_wwn(tpg),
			tpg->se_tpg_tfo->tpg_get_tag(tpg),
			pr_reg->tg_pt_sep_rtpi, pr_reg->pr_aptpl_target_lun,
			reg_count);

		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
			pr_err("Unable to update renaming APTPL metadata,"
			       " reallocating larger buffer\n");
			ret = -EMSGSIZE;
			goto out;
		}
		len += sprintf(buf+len, "%s", tmp);
		reg_count++;
	}

	if (!reg_count)
		len += sprintf(buf+len, "No Registrations or Reservations");

out:
	spin_unlock(&dev->t10_pr.registration_lock);
	spin_unlock(&dev->dev_reservation_lock);

	return ret;
}

static int __core_scsi3_write_aptpl_to_file(
	struct se_device *dev,
	unsigned char *buf)
{
	struct t10_wwn *wwn = &dev->t10_wwn;
	struct file *file;
	int flags = O_RDWR | O_CREAT | O_TRUNC;
	char *path;
	u32 pr_aptpl_buf_len;
	int ret;
	loff_t pos = 0;

	path = kasprintf(GFP_KERNEL, "%s/pr/aptpl_%s", db_root,
			&wwn->unit_serial[0]);
	if (!path)
		return -ENOMEM;

	file = filp_open(path, flags, 0600);
	if (IS_ERR(file)) {
		pr_err("filp_open(%s) for APTPL metadata"
			" failed\n", path);
		kfree(path);
		return PTR_ERR(file);
	}

	pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */

	ret = kernel_write(file, buf, pr_aptpl_buf_len, &pos);

	if (ret < 0)
		pr_debug("Error writing APTPL metadata file: %s\n", path);
	fput(file);
	kfree(path);

	return (ret < 0) ? -EIO : 0;
}

/*
 * Clear the APTPL metadata if APTPL has been disabled, otherwise
 * write out the updated metadata to struct file for this SCSI device.
 */
static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl)
{
	unsigned char *buf;
	int rc, len = PR_APTPL_BUF_LEN;

	if (!aptpl) {
		char *null_buf = "No Registrations or Reservations\n";

		rc = __core_scsi3_write_aptpl_to_file(dev, null_buf);
		dev->t10_pr.pr_aptpl_active = 0;
		pr_debug("SPC-3 PR: Set APTPL Bit Deactivated\n");

		if (rc)
			return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

		return 0;
	}
retry:
	buf = vzalloc(len);
	if (!buf)
		return TCM_OUT_OF_RESOURCES;

	rc = core_scsi3_update_aptpl_buf(dev, buf, len);
	if (rc < 0) {
		vfree(buf);
		len *= 2;
		goto retry;
	}

	rc = __core_scsi3_write_aptpl_to_file(dev, buf);
	if (rc != 0) {
		pr_err("SPC-3 PR: Could not update APTPL\n");
		vfree(buf);
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	dev->t10_pr.pr_aptpl_active = 1;
	vfree(buf);
	pr_debug("SPC-3 PR: Set APTPL Bit Activated\n");
	return 0;
}

static sense_reason_t
core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
		bool aptpl, bool all_tg_pt, bool spec_i_pt, enum register_type register_type)
{
	struct se_session *se_sess = cmd->se_sess;
	struct se_device *dev = cmd->se_dev;
	struct se_lun *se_lun = cmd->se_lun;
	struct se_portal_group *se_tpg;
	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
	sense_reason_t ret = TCM_NO_SENSE;
	int pr_holder = 0, type;

	if (!se_sess || !se_lun) {
		pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	se_tpg = se_sess->se_tpg;

	if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) {
		memset(&isid_buf[0], 0, PR_REG_ISID_LEN);
		se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, &isid_buf[0],
				PR_REG_ISID_LEN);
		isid_ptr = &isid_buf[0];
	}
	/*
	 * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47
	 */
	pr_reg = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess);
	if (!pr_reg) {
		if (res_key) {
			pr_warn("SPC-3 PR: Reservation Key non-zero"
				" for SA REGISTER, returning CONFLICT\n");
			return TCM_RESERVATION_CONFLICT;
		}
		/*
		 * Do nothing but return GOOD status.
		 */
		if (!sa_res_key)
			return 0;

		if (!spec_i_pt) {
			/*
			 * Perform the Service Action REGISTER on the Initiator
			 * Port Endpoint that the PRO was received from on the
			 * Logical Unit of the SCSI device server.
			 */
			if (core_scsi3_alloc_registration(cmd->se_dev,
					se_sess->se_node_acl, cmd->se_lun,
					NULL, cmd->orig_fe_lun, isid_ptr,
					sa_res_key, all_tg_pt, aptpl,
					register_type, 0)) {
				pr_err("Unable to allocate"
					" struct t10_pr_registration\n");
				return TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
			}
		} else {
			/*
			 * Register both the Initiator port that received
			 * PROUT SA REGISTER + SPEC_I_PT=1 and extract SCSI
			 * TransportID from Parameter list and loop through
			 * fabric dependent parameter list while calling
			 * logic from of core_scsi3_alloc_registration() for
			 * each TransportID provided SCSI Initiator Port/Device
			 */
			ret = core_scsi3_decode_spec_i_port(cmd, se_tpg,
					isid_ptr, sa_res_key, all_tg_pt, aptpl);
			if (ret != 0)
				return ret;
		}
		return core_scsi3_update_and_write_aptpl(dev, aptpl);
	}

	/* ok, existing registration */

	if ((register_type == REGISTER) && (res_key != pr_reg->pr_res_key)) {
		pr_err("SPC-3 PR REGISTER: Received"
		       " res_key: 0x%016Lx does not match"
		       " existing SA REGISTER res_key:"
		       " 0x%016Lx\n", res_key,
		       pr_reg->pr_res_key);
		ret = TCM_RESERVATION_CONFLICT;
		goto out;
	}

	if (spec_i_pt) {
		pr_err("SPC-3 PR REGISTER: SPEC_I_PT"
			" set on a registered nexus\n");
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	/*
	 * An existing ALL_TG_PT=1 registration being released
	 * must also set ALL_TG_PT=1 in the incoming PROUT.
	 */
	if (pr_reg->pr_reg_all_tg_pt && !all_tg_pt) {
		pr_err("SPC-3 PR REGISTER: ALL_TG_PT=1"
			" registration exists, but ALL_TG_PT=1 bit not"
			" present in received PROUT\n");
		ret = TCM_INVALID_CDB_FIELD;
		goto out;
	}

	/*
	 * sa_res_key=1 Change Reservation Key for registered I_T Nexus.
	 */
	if (sa_res_key) {
		/*
		 * Increment PRgeneration counter for struct se_device"
		 * upon a successful REGISTER, see spc4r17 section 6.3.2
		 * READ_KEYS service action.
		 */
		pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev);
		pr_reg->pr_res_key = sa_res_key;
		pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
			 " Key for %s to: 0x%016Lx PRgeneration:"
			 " 0x%08x\n", cmd->se_tfo->fabric_name,
			 (register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ? "_AND_IGNORE_EXISTING_KEY" : "",
			 pr_reg->pr_reg_nacl->initiatorname,
			 pr_reg->pr_res_key, pr_reg->pr_res_generation);

	} else {
		/*
		 * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus.
		 */
		type = pr_reg->pr_res_type;
		pr_holder = core_scsi3_check_implicit_release(cmd->se_dev,
							      pr_reg);
		if (pr_holder < 0) {
			ret = TCM_RESERVATION_CONFLICT;
			goto out;
		}

		spin_lock(&pr_tmpl->registration_lock);
		/*
		 * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port
		 * and matching pr_res_key.
		 */
		if (pr_reg->pr_reg_all_tg_pt) {
			list_for_each_entry_safe(pr_reg_p, pr_reg_tmp,
					&pr_tmpl->registration_list,
					pr_reg_list) {

				if (!pr_reg_p->pr_reg_all_tg_pt)
					continue;
				if (pr_reg_p->pr_res_key != res_key)
					continue;
				if (pr_reg == pr_reg_p)
					continue;
				if (strcmp(pr_reg->pr_reg_nacl->initiatorname,
					   pr_reg_p->pr_reg_nacl->initiatorname))
					continue;

				__core_scsi3_free_registration(dev,
						pr_reg_p, NULL, 0);
			}
		}

		/*
		 * Release the calling I_T Nexus registration now..
		 */
		__core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1);
		pr_reg = NULL;

		/*
		 * From spc4r17, section 5.7.11.3 Unregistering
		 *
		 * If the persistent reservation is a registrants only
		 * type, the device server shall establish a unit
		 * attention condition for the initiator port associated
		 * with every registered I_T nexus except for the I_T
		 * nexus on which the PERSISTENT RESERVE OUT command was
		 * received, with the additional sense code set to
		 * RESERVATIONS RELEASED.
		 */
		if (pr_holder &&
		    (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY ||
		     type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) {
			list_for_each_entry(pr_reg_p,
					&pr_tmpl->registration_list,
					pr_reg_list) {

				target_ua_allocate_lun(
					pr_reg_p->pr_reg_nacl,
					pr_reg_p->pr_res_mapped_lun,
					0x2A,
					ASCQ_2AH_RESERVATIONS_RELEASED);
			}
		}

		spin_unlock(&pr_tmpl->registration_lock);
	}

	ret = core_scsi3_update_and_write_aptpl(dev, aptpl);

out:
	if (pr_reg)
		core_scsi3_put_pr_reg(pr_reg);
	return ret;
}

unsigned char *core_scsi3_pr_dump_type(int type)
{
	switch (type) {
	case PR_TYPE_WRITE_EXCLUSIVE:
		return "Write Exclusive Access";
	case PR_TYPE_EXCLUSIVE_ACCESS:
		return "Exclusive Access";
	case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
		return "Write Exclusive Access, Registrants Only";
	case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
		return "Exclusive Access, Registrants Only";
	case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
		return "Write Exclusive Access, All Registrants";
	case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
		return "Exclusive Access, All Registrants";
	default:
		break;
	}

	return "Unknown SPC-3 PR Type";
}

static sense_reason_t
core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *se_sess = cmd->se_sess;
	struct se_lun *se_lun = cmd->se_lun;
	struct t10_pr_registration *pr_reg, *pr_res_holder;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	char i_buf[PR_REG_ISID_ID_LEN];
	sense_reason_t ret;

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);

	if (!se_sess || !se_lun) {
		pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * Locate the existing *pr_reg via struct se_node_acl pointers
	 */
	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
				se_sess);
	if (!pr_reg) {
		pr_err("SPC-3 PR: Unable to locate"
			" PR_REGISTERED *pr_reg for RESERVE\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * From spc4r17 Section 5.7.9: Reserving:
	 *
	 * An application client creates a persistent reservation by issuing
	 * a PERSISTENT RESERVE OUT command with RESERVE service action through
	 * a registered I_T nexus with the following parameters:
	 *    a) RESERVATION KEY set to the value of the reservation key that is
	 * 	 registered with the logical unit for the I_T nexus; and
	 */
	if (res_key != pr_reg->pr_res_key) {
		pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx"
			" does not match existing SA REGISTER res_key:"
			" 0x%016Lx\n", res_key, pr_reg->pr_res_key);
		ret = TCM_RESERVATION_CONFLICT;
		goto out_put_pr_reg;
	}
	/*
	 * From spc4r17 Section 5.7.9: Reserving:
	 *
	 * From above:
	 *  b) TYPE field and SCOPE field set to the persistent reservation
	 *     being created.
	 *
	 * Only one persistent reservation is allowed at a time per logical unit
	 * and that persistent reservation has a scope of LU_SCOPE.
	 */
	if (scope != PR_SCOPE_LU_SCOPE) {
		pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out_put_pr_reg;
	}
	/*
	 * See if we have an existing PR reservation holder pointer at
	 * struct se_device->dev_pr_res_holder in the form struct t10_pr_registration
	 * *pr_res_holder.
	 */
	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (pr_res_holder) {
		/*
		 * From spc4r17 Section 5.7.9: Reserving:
		 *
		 * If the device server receives a PERSISTENT RESERVE OUT
		 * command from an I_T nexus other than a persistent reservation
		 * holder (see 5.7.10) that attempts to create a persistent
		 * reservation when a persistent reservation already exists for
		 * the logical unit, then the command shall be completed with
		 * RESERVATION CONFLICT status.
		 */
		if (!is_reservation_holder(pr_res_holder, pr_reg)) {
			struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
			pr_err("SPC-3 PR: Attempted RESERVE from"
				" [%s]: %s while reservation already held by"
				" [%s]: %s, returning RESERVATION_CONFLICT\n",
				cmd->se_tfo->fabric_name,
				se_sess->se_node_acl->initiatorname,
				pr_res_nacl->se_tpg->se_tpg_tfo->fabric_name,
				pr_res_holder->pr_reg_nacl->initiatorname);

			spin_unlock(&dev->dev_reservation_lock);
			ret = TCM_RESERVATION_CONFLICT;
			goto out_put_pr_reg;
		}
		/*
		 * From spc4r17 Section 5.7.9: Reserving:
		 *
		 * If a persistent reservation holder attempts to modify the
		 * type or scope of an existing persistent reservation, the
		 * command shall be completed with RESERVATION CONFLICT status.
		 */
		if ((pr_res_holder->pr_res_type != type) ||
		    (pr_res_holder->pr_res_scope != scope)) {
			struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
			pr_err("SPC-3 PR: Attempted RESERVE from"
				" [%s]: %s trying to change TYPE and/or SCOPE,"
				" while reservation already held by [%s]: %s,"
				" returning RESERVATION_CONFLICT\n",
				cmd->se_tfo->fabric_name,
				se_sess->se_node_acl->initiatorname,
				pr_res_nacl->se_tpg->se_tpg_tfo->fabric_name,
				pr_res_holder->pr_reg_nacl->initiatorname);

			spin_unlock(&dev->dev_reservation_lock);
			ret = TCM_RESERVATION_CONFLICT;
			goto out_put_pr_reg;
		}
		/*
		 * From spc4r17 Section 5.7.9: Reserving:
		 *
		 * If the device server receives a PERSISTENT RESERVE OUT
		 * command with RESERVE service action where the TYPE field and
		 * the SCOPE field contain the same values as the existing type
		 * and scope from a persistent reservation holder, it shall not
		 * make any change to the existing persistent reservation and
		 * shall completethe command with GOOD status.
		 */
		spin_unlock(&dev->dev_reservation_lock);
		ret = 0;
		goto out_put_pr_reg;
	}
	/*
	 * Otherwise, our *pr_reg becomes the PR reservation holder for said
	 * TYPE/SCOPE.  Also set the received scope and type in *pr_reg.
	 */
	pr_reg->pr_res_scope = scope;
	pr_reg->pr_res_type = type;
	pr_reg->pr_res_holder = 1;
	dev->dev_pr_res_holder = pr_reg;
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);

	pr_debug("SPC-3 PR [%s] Service Action: RESERVE created new"
		" reservation holder TYPE: %s ALL_TG_PT: %d\n",
		cmd->se_tfo->fabric_name, core_scsi3_pr_dump_type(type),
		(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
	pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n",
			cmd->se_tfo->fabric_name,
			se_sess->se_node_acl->initiatorname,
			i_buf);
	spin_unlock(&dev->dev_reservation_lock);

	if (pr_tmpl->pr_aptpl_active)
		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);

	ret = 0;
out_put_pr_reg:
	core_scsi3_put_pr_reg(pr_reg);
	return ret;
}

static sense_reason_t
core_scsi3_emulate_pro_reserve(struct se_cmd *cmd, int type, int scope,
		u64 res_key)
{
	switch (type) {
	case PR_TYPE_WRITE_EXCLUSIVE:
	case PR_TYPE_EXCLUSIVE_ACCESS:
	case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
	case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
	case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
	case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
		return core_scsi3_pro_reserve(cmd, type, scope, res_key);
	default:
		pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:"
			" 0x%02x\n", type);
		return TCM_INVALID_CDB_FIELD;
	}
}

static void __core_scsi3_complete_pro_release(
	struct se_device *dev,
	struct se_node_acl *se_nacl,
	struct t10_pr_registration *pr_reg,
	int explicit,
	int unreg)
{
	const struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo;
	char i_buf[PR_REG_ISID_ID_LEN];
	int pr_res_type = 0, pr_res_scope = 0;

	lockdep_assert_held(&dev->dev_reservation_lock);

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);
	/*
	 * Go ahead and release the current PR reservation holder.
	 * If an All Registrants reservation is currently active and
	 * a unregister operation is requested, replace the current
	 * dev_pr_res_holder with another active registration.
	 */
	if (dev->dev_pr_res_holder) {
		pr_res_type = dev->dev_pr_res_holder->pr_res_type;
		pr_res_scope = dev->dev_pr_res_holder->pr_res_scope;
		dev->dev_pr_res_holder->pr_res_type = 0;
		dev->dev_pr_res_holder->pr_res_scope = 0;
		dev->dev_pr_res_holder->pr_res_holder = 0;
		dev->dev_pr_res_holder = NULL;
	}
	if (!unreg)
		goto out;

	spin_lock(&dev->t10_pr.registration_lock);
	list_del_init(&pr_reg->pr_reg_list);
	/*
	 * If the I_T nexus is a reservation holder, the persistent reservation
	 * is of an all registrants type, and the I_T nexus is the last remaining
	 * registered I_T nexus, then the device server shall also release the
	 * persistent reservation.
	 */
	if (!list_empty(&dev->t10_pr.registration_list) &&
	    ((pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
	     (pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))) {
		dev->dev_pr_res_holder =
			list_entry(dev->t10_pr.registration_list.next,
				   struct t10_pr_registration, pr_reg_list);
		dev->dev_pr_res_holder->pr_res_type = pr_res_type;
		dev->dev_pr_res_holder->pr_res_scope = pr_res_scope;
		dev->dev_pr_res_holder->pr_res_holder = 1;
	}
	spin_unlock(&dev->t10_pr.registration_lock);
out:
	if (!dev->dev_pr_res_holder) {
		pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared"
			" reservation holder TYPE: %s ALL_TG_PT: %d\n",
			tfo->fabric_name, (explicit) ? "explicit" :
			"implicit", core_scsi3_pr_dump_type(pr_res_type),
			(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
	}
	pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n",
		tfo->fabric_name, se_nacl->initiatorname,
		i_buf);
	/*
	 * Clear TYPE and SCOPE for the next PROUT Service Action: RESERVE
	 */
	pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0;
}

static sense_reason_t
core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope,
		u64 res_key)
{
	struct se_device *dev = cmd->se_dev;
	struct se_session *se_sess = cmd->se_sess;
	struct se_lun *se_lun = cmd->se_lun;
	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	sense_reason_t ret = 0;

	if (!se_sess || !se_lun) {
		pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * Locate the existing *pr_reg via struct se_node_acl pointers
	 */
	pr_reg = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess);
	if (!pr_reg) {
		pr_err("SPC-3 PR: Unable to locate"
			" PR_REGISTERED *pr_reg for RELEASE\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * From spc4r17 Section 5.7.11.2 Releasing:
	 *
	 * If there is no persistent reservation or in response to a persistent
	 * reservation release request from a registered I_T nexus that is not a
	 * persistent reservation holder (see 5.7.10), the device server shall
	 * do the following:
	 *
	 *     a) Not release the persistent reservation, if any;
	 *     b) Not remove any registrations; and
	 *     c) Complete the command with GOOD status.
	 */
	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (!pr_res_holder) {
		/*
		 * No persistent reservation, return GOOD status.
		 */
		spin_unlock(&dev->dev_reservation_lock);
		goto out_put_pr_reg;
	}

	if (!is_reservation_holder(pr_res_holder, pr_reg)) {
		/*
		 * Release request from a registered I_T nexus that is not a
		 * persistent reservation holder. return GOOD status.
		 */
		spin_unlock(&dev->dev_reservation_lock);
		goto out_put_pr_reg;
	}

	/*
	 * From spc4r17 Section 5.7.11.2 Releasing:
	 *
	 * Only the persistent reservation holder (see 5.7.10) is allowed to
	 * release a persistent reservation.
	 *
	 * An application client releases the persistent reservation by issuing
	 * a PERSISTENT RESERVE OUT command with RELEASE service action through
	 * an I_T nexus that is a persistent reservation holder with the
	 * following parameters:
	 *
	 *     a) RESERVATION KEY field set to the value of the reservation key
	 *	  that is registered with the logical unit for the I_T nexus;
	 */
	if (res_key != pr_reg->pr_res_key) {
		pr_err("SPC-3 PR RELEASE: Received res_key: 0x%016Lx"
			" does not match existing SA REGISTER res_key:"
			" 0x%016Lx\n", res_key, pr_reg->pr_res_key);
		spin_unlock(&dev->dev_reservation_lock);
		ret = TCM_RESERVATION_CONFLICT;
		goto out_put_pr_reg;
	}
	/*
	 * From spc4r17 Section 5.7.11.2 Releasing and above:
	 *
	 * b) TYPE field and SCOPE field set to match the persistent
	 *    reservation being released.
	 */
	if ((pr_res_holder->pr_res_type != type) ||
	    (pr_res_holder->pr_res_scope != scope)) {
		struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
		pr_err("SPC-3 PR RELEASE: Attempted to release"
			" reservation from [%s]: %s with different TYPE "
			"and/or SCOPE  while reservation already held by"
			" [%s]: %s, returning RESERVATION_CONFLICT\n",
			cmd->se_tfo->fabric_name,
			se_sess->se_node_acl->initiatorname,
			pr_res_nacl->se_tpg->se_tpg_tfo->fabric_name,
			pr_res_holder->pr_reg_nacl->initiatorname);

		spin_unlock(&dev->dev_reservation_lock);
		ret = TCM_RESERVATION_CONFLICT;
		goto out_put_pr_reg;
	}
	/*
	 * In response to a persistent reservation release request from the
	 * persistent reservation holder the device server shall perform a
	 * release by doing the following as an uninterrupted series of actions:
	 * a) Release the persistent reservation;
	 * b) Not remove any registration(s);
	 * c) If the released persistent reservation is a registrants only type
	 * or all registrants type persistent reservation,
	 *    the device server shall establish a unit attention condition for
	 *    the initiator port associated with every regis-
	 *    tered I_T nexus other than I_T nexus on which the PERSISTENT
	 *    RESERVE OUT command with RELEASE service action was received,
	 *    with the additional sense code set to RESERVATIONS RELEASED; and
	 * d) If the persistent reservation is of any other type, the device
	 *    server shall not establish a unit attention condition.
	 */
	__core_scsi3_complete_pro_release(dev, se_sess->se_node_acl,
					  pr_reg, 1, 0);

	spin_unlock(&dev->dev_reservation_lock);

	if ((type != PR_TYPE_WRITE_EXCLUSIVE_REGONLY) &&
	    (type != PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) &&
	    (type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) &&
	    (type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
		/*
		 * If no UNIT ATTENTION conditions will be established for
		 * PR_TYPE_WRITE_EXCLUSIVE or PR_TYPE_EXCLUSIVE_ACCESS
		 * go ahead and check for APTPL=1 update+write below
		 */
		goto write_aptpl;
	}

	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry(pr_reg_p, &pr_tmpl->registration_list,
			pr_reg_list) {
		/*
		 * Do not establish a UNIT ATTENTION condition
		 * for the calling I_T Nexus
		 */
		if (pr_reg_p == pr_reg)
			continue;

		target_ua_allocate_lun(pr_reg_p->pr_reg_nacl,
				pr_reg_p->pr_res_mapped_lun,
				0x2A, ASCQ_2AH_RESERVATIONS_RELEASED);
	}
	spin_unlock(&pr_tmpl->registration_lock);

write_aptpl:
	if (pr_tmpl->pr_aptpl_active)
		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);

out_put_pr_reg:
	core_scsi3_put_pr_reg(pr_reg);
	return ret;
}

static sense_reason_t
core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key)
{
	struct se_device *dev = cmd->se_dev;
	struct se_node_acl *pr_reg_nacl;
	struct se_session *se_sess = cmd->se_sess;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
	u64 pr_res_mapped_lun = 0;
	int calling_it_nexus = 0;
	/*
	 * Locate the existing *pr_reg via struct se_node_acl pointers
	 */
	pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev,
			se_sess->se_node_acl, se_sess);
	if (!pr_reg_n) {
		pr_err("SPC-3 PR: Unable to locate"
			" PR_REGISTERED *pr_reg for CLEAR\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * From spc4r17 section 5.7.11.6, Clearing:
	 *
	 * Any application client may release the persistent reservation and
	 * remove all registrations from a device server by issuing a
	 * PERSISTENT RESERVE OUT command with CLEAR service action through a
	 * registered I_T nexus with the following parameter:
	 *
	 *	a) RESERVATION KEY field set to the value of the reservation key
	 * 	   that is registered with the logical unit for the I_T nexus.
	 */
	if (res_key != pr_reg_n->pr_res_key) {
		pr_err("SPC-3 PR REGISTER: Received"
			" res_key: 0x%016Lx does not match"
			" existing SA REGISTER res_key:"
			" 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
		core_scsi3_put_pr_reg(pr_reg_n);
		return TCM_RESERVATION_CONFLICT;
	}
	/*
	 * a) Release the persistent reservation, if any;
	 */
	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (pr_res_holder) {
		struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
		__core_scsi3_complete_pro_release(dev, pr_res_nacl,
						  pr_res_holder, 0, 0);
	}
	spin_unlock(&dev->dev_reservation_lock);
	/*
	 * b) Remove all registration(s) (see spc4r17 5.7.7);
	 */
	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {

		calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
		pr_reg_nacl = pr_reg->pr_reg_nacl;
		pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
		__core_scsi3_free_registration(dev, pr_reg, NULL,
					calling_it_nexus);
		/*
		 * e) Establish a unit attention condition for the initiator
		 *    port associated with every registered I_T nexus other
		 *    than the I_T nexus on which the PERSISTENT RESERVE OUT
		 *    command with CLEAR service action was received, with the
		 *    additional sense code set to RESERVATIONS PREEMPTED.
		 */
		if (!calling_it_nexus)
			target_ua_allocate_lun(pr_reg_nacl, pr_res_mapped_lun,
				0x2A, ASCQ_2AH_RESERVATIONS_PREEMPTED);
	}
	spin_unlock(&pr_tmpl->registration_lock);

	pr_debug("SPC-3 PR [%s] Service Action: CLEAR complete\n",
		cmd->se_tfo->fabric_name);

	core_scsi3_update_and_write_aptpl(cmd->se_dev, false);

	core_scsi3_pr_generation(dev);
	return 0;
}

static void __core_scsi3_complete_pro_preempt(
	struct se_device *dev,
	struct t10_pr_registration *pr_reg,
	struct list_head *preempt_and_abort_list,
	int type,
	int scope,
	enum preempt_type preempt_type)
{
	struct se_node_acl *nacl = pr_reg->pr_reg_nacl;
	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
	char i_buf[PR_REG_ISID_ID_LEN];

	lockdep_assert_held(&dev->dev_reservation_lock);

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);
	/*
	 * Do an implicit RELEASE of the existing reservation.
	 */
	if (dev->dev_pr_res_holder)
		__core_scsi3_complete_pro_release(dev, nacl,
						  dev->dev_pr_res_holder, 0, 0);

	dev->dev_pr_res_holder = pr_reg;
	pr_reg->pr_res_holder = 1;
	pr_reg->pr_res_type = type;
	pr_reg->pr_res_scope = scope;

	pr_debug("SPC-3 PR [%s] Service Action: PREEMPT%s created new"
		" reservation holder TYPE: %s ALL_TG_PT: %d\n",
		tfo->fabric_name, (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "",
		core_scsi3_pr_dump_type(type),
		(pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
	pr_debug("SPC-3 PR [%s] PREEMPT%s from Node: %s%s\n",
		tfo->fabric_name, (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "",
		nacl->initiatorname, i_buf);
	/*
	 * For PREEMPT_AND_ABORT, add the preempting reservation's
	 * struct t10_pr_registration to the list that will be compared
	 * against received CDBs..
	 */
	if (preempt_and_abort_list)
		list_add_tail(&pr_reg->pr_reg_abort_list,
				preempt_and_abort_list);
}

static void core_scsi3_release_preempt_and_abort(
	struct list_head *preempt_and_abort_list,
	struct t10_pr_registration *pr_reg_holder)
{
	struct t10_pr_registration *pr_reg, *pr_reg_tmp;

	list_for_each_entry_safe(pr_reg, pr_reg_tmp, preempt_and_abort_list,
				pr_reg_abort_list) {

		list_del(&pr_reg->pr_reg_abort_list);
		if (pr_reg_holder == pr_reg)
			continue;
		if (pr_reg->pr_res_holder) {
			pr_warn("pr_reg->pr_res_holder still set\n");
			continue;
		}

		pr_reg->pr_reg_deve = NULL;
		pr_reg->pr_reg_nacl = NULL;
		kmem_cache_free(t10_pr_reg_cache, pr_reg);
	}
}

static sense_reason_t
core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
		u64 sa_res_key, enum preempt_type preempt_type)
{
	struct se_device *dev = cmd->se_dev;
	struct se_node_acl *pr_reg_nacl;
	struct se_session *se_sess = cmd->se_sess;
	LIST_HEAD(preempt_and_abort_list);
	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	u64 pr_res_mapped_lun = 0;
	int all_reg = 0, calling_it_nexus = 0;
	bool sa_res_key_unmatched = sa_res_key != 0;
	int prh_type = 0, prh_scope = 0;

	if (!se_sess)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
				se_sess);
	if (!pr_reg_n) {
		pr_err("SPC-3 PR: Unable to locate"
			" PR_REGISTERED *pr_reg for PREEMPT%s\n",
			(preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "");
		return TCM_RESERVATION_CONFLICT;
	}
	if (pr_reg_n->pr_res_key != res_key) {
		core_scsi3_put_pr_reg(pr_reg_n);
		return TCM_RESERVATION_CONFLICT;
	}
	if (scope != PR_SCOPE_LU_SCOPE) {
		pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
		core_scsi3_put_pr_reg(pr_reg_n);
		return TCM_INVALID_PARAMETER_LIST;
	}

	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (pr_res_holder &&
	   ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
	    (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)))
		all_reg = 1;

	if (!all_reg && !sa_res_key) {
		spin_unlock(&dev->dev_reservation_lock);
		core_scsi3_put_pr_reg(pr_reg_n);
		return TCM_INVALID_PARAMETER_LIST;
	}
	/*
	 * From spc4r17, section 5.7.11.4.4 Removing Registrations:
	 *
	 * If the SERVICE ACTION RESERVATION KEY field does not identify a
	 * persistent reservation holder or there is no persistent reservation
	 * holder (i.e., there is no persistent reservation), then the device
	 * server shall perform a preempt by doing the following in an
	 * uninterrupted series of actions. (See below..)
	 */
	if (!pr_res_holder || (pr_res_holder->pr_res_key != sa_res_key)) {
		/*
		 * No existing or SA Reservation Key matching reservations..
		 *
		 * PROUT SA PREEMPT with All Registrant type reservations are
		 * allowed to be processed without a matching SA Reservation Key
		 */
		spin_lock(&pr_tmpl->registration_lock);
		list_for_each_entry_safe(pr_reg, pr_reg_tmp,
				&pr_tmpl->registration_list, pr_reg_list) {
			/*
			 * Removing of registrations in non all registrants
			 * type reservations without a matching SA reservation
			 * key.
			 *
			 * a) Remove the registrations for all I_T nexuses
			 *    specified by the SERVICE ACTION RESERVATION KEY
			 *    field;
			 * b) Ignore the contents of the SCOPE and TYPE fields;
			 * c) Process tasks as defined in 5.7.1; and
			 * d) Establish a unit attention condition for the
			 *    initiator port associated with every I_T nexus
			 *    that lost its registration other than the I_T
			 *    nexus on which the PERSISTENT RESERVE OUT command
			 *    was received, with the additional sense code set
			 *    to REGISTRATIONS PREEMPTED.
			 */
			if (!all_reg) {
				if (pr_reg->pr_res_key != sa_res_key)
					continue;
				sa_res_key_unmatched = false;

				calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
				pr_reg_nacl = pr_reg->pr_reg_nacl;
				pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
				__core_scsi3_free_registration(dev, pr_reg,
					(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
						NULL, calling_it_nexus);
			} else {
				/*
				 * Case for any existing all registrants type
				 * reservation, follow logic in spc4r17 section
				 * 5.7.11.4 Preempting, Table 52 and Figure 7.
				 *
				 * For a ZERO SA Reservation key, release
				 * all other registrations and do an implicit
				 * release of active persistent reservation.
				 *
				 * For a non-ZERO SA Reservation key, only
				 * release the matching reservation key from
				 * registrations.
				 */
				if ((sa_res_key) &&
				     (pr_reg->pr_res_key != sa_res_key))
					continue;
				sa_res_key_unmatched = false;

				calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
				if (calling_it_nexus)
					continue;

				pr_reg_nacl = pr_reg->pr_reg_nacl;
				pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
				__core_scsi3_free_registration(dev, pr_reg,
					(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
						NULL, 0);
			}
			if (!calling_it_nexus)
				target_ua_allocate_lun(pr_reg_nacl,
					pr_res_mapped_lun, 0x2A,
					ASCQ_2AH_REGISTRATIONS_PREEMPTED);
		}
		spin_unlock(&pr_tmpl->registration_lock);
		/*
		 * If a PERSISTENT RESERVE OUT with a PREEMPT service action or
		 * a PREEMPT AND ABORT service action sets the SERVICE ACTION
		 * RESERVATION KEY field to a value that does not match any
		 * registered reservation key, then the device server shall
		 * complete the command with RESERVATION CONFLICT status.
		 */
		if (sa_res_key_unmatched) {
			spin_unlock(&dev->dev_reservation_lock);
			core_scsi3_put_pr_reg(pr_reg_n);
			return TCM_RESERVATION_CONFLICT;
		}
		/*
		 * For an existing all registrants type reservation
		 * with a zero SA rservation key, preempt the existing
		 * reservation with the new PR type and scope.
		 */
		if (pr_res_holder && all_reg && !(sa_res_key)) {
			__core_scsi3_complete_pro_preempt(dev, pr_reg_n,
				(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL,
				type, scope, preempt_type);

			if (preempt_type == PREEMPT_AND_ABORT)
				core_scsi3_release_preempt_and_abort(
					&preempt_and_abort_list, pr_reg_n);
		}
		spin_unlock(&dev->dev_reservation_lock);

		if (pr_tmpl->pr_aptpl_active)
			core_scsi3_update_and_write_aptpl(cmd->se_dev, true);

		core_scsi3_put_pr_reg(pr_reg_n);
		core_scsi3_pr_generation(cmd->se_dev);
		return 0;
	}
	/*
	 * The PREEMPTing SA reservation key matches that of the
	 * existing persistent reservation, first, we check if
	 * we are preempting our own reservation.
	 * From spc4r17, section 5.7.11.4.3 Preempting
	 * persistent reservations and registration handling
	 *
	 * If an all registrants persistent reservation is not
	 * present, it is not an error for the persistent
	 * reservation holder to preempt itself (i.e., a
	 * PERSISTENT RESERVE OUT with a PREEMPT service action
	 * or a PREEMPT AND ABORT service action with the
	 * SERVICE ACTION RESERVATION KEY value equal to the
	 * persistent reservation holder's reservation key that
	 * is received from the persistent reservation holder).
	 * In that case, the device server shall establish the
	 * new persistent reservation and maintain the
	 * registration.
	 */
	prh_type = pr_res_holder->pr_res_type;
	prh_scope = pr_res_holder->pr_res_scope;
	/*
	 * If the SERVICE ACTION RESERVATION KEY field identifies a
	 * persistent reservation holder (see 5.7.10), the device
	 * server shall perform a preempt by doing the following as
	 * an uninterrupted series of actions:
	 *
	 * a) Release the persistent reservation for the holder
	 *    identified by the SERVICE ACTION RESERVATION KEY field;
	 */
	if (pr_reg_n != pr_res_holder)
		__core_scsi3_complete_pro_release(dev,
						  pr_res_holder->pr_reg_nacl,
						  dev->dev_pr_res_holder, 0, 0);
	/*
	 * b) Remove the registrations for all I_T nexuses identified
	 *    by the SERVICE ACTION RESERVATION KEY field, except the
	 *    I_T nexus that is being used for the PERSISTENT RESERVE
	 *    OUT command. If an all registrants persistent reservation
	 *    is present and the SERVICE ACTION RESERVATION KEY field
	 *    is set to zero, then all registrations shall be removed
	 *    except for that of the I_T nexus that is being used for
	 *    the PERSISTENT RESERVE OUT command;
	 */
	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {

		calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
		if (calling_it_nexus)
			continue;

		if (pr_reg->pr_res_key != sa_res_key)
			continue;

		pr_reg_nacl = pr_reg->pr_reg_nacl;
		pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
		__core_scsi3_free_registration(dev, pr_reg,
				(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL,
				calling_it_nexus);
		/*
		 * e) Establish a unit attention condition for the initiator
		 *    port associated with every I_T nexus that lost its
		 *    persistent reservation and/or registration, with the
		 *    additional sense code set to REGISTRATIONS PREEMPTED;
		 */
		target_ua_allocate_lun(pr_reg_nacl, pr_res_mapped_lun, 0x2A,
				ASCQ_2AH_REGISTRATIONS_PREEMPTED);
	}
	spin_unlock(&pr_tmpl->registration_lock);
	/*
	 * c) Establish a persistent reservation for the preempting
	 *    I_T nexus using the contents of the SCOPE and TYPE fields;
	 */
	__core_scsi3_complete_pro_preempt(dev, pr_reg_n,
			(preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL,
			type, scope, preempt_type);
	/*
	 * d) Process tasks as defined in 5.7.1;
	 * e) See above..
	 * f) If the type or scope has changed, then for every I_T nexus
	 *    whose reservation key was not removed, except for the I_T
	 *    nexus on which the PERSISTENT RESERVE OUT command was
	 *    received, the device server shall establish a unit
	 *    attention condition for the initiator port associated with
	 *    that I_T nexus, with the additional sense code set to
	 *    RESERVATIONS RELEASED. If the type or scope have not
	 *    changed, then no unit attention condition(s) shall be
	 *    established for this reason.
	 */
	if ((prh_type != type) || (prh_scope != scope)) {
		spin_lock(&pr_tmpl->registration_lock);
		list_for_each_entry_safe(pr_reg, pr_reg_tmp,
				&pr_tmpl->registration_list, pr_reg_list) {

			calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
			if (calling_it_nexus)
				continue;

			target_ua_allocate_lun(pr_reg->pr_reg_nacl,
					pr_reg->pr_res_mapped_lun, 0x2A,
					ASCQ_2AH_RESERVATIONS_RELEASED);
		}
		spin_unlock(&pr_tmpl->registration_lock);
	}
	spin_unlock(&dev->dev_reservation_lock);
	/*
	 * Call LUN_RESET logic upon list of struct t10_pr_registration,
	 * All received CDBs for the matching existing reservation and
	 * registrations undergo ABORT_TASK logic.
	 *
	 * From there, core_scsi3_release_preempt_and_abort() will
	 * release every registration in the list (which have already
	 * been removed from the primary pr_reg list), except the
	 * new persistent reservation holder, the calling Initiator Port.
	 */
	if (preempt_type == PREEMPT_AND_ABORT) {
		core_tmr_lun_reset(dev, NULL, &preempt_and_abort_list, cmd);
		core_scsi3_release_preempt_and_abort(&preempt_and_abort_list,
						pr_reg_n);
	}

	if (pr_tmpl->pr_aptpl_active)
		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);

	core_scsi3_put_pr_reg(pr_reg_n);
	core_scsi3_pr_generation(cmd->se_dev);
	return 0;
}

static sense_reason_t
core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope,
		u64 res_key, u64 sa_res_key, enum preempt_type preempt_type)
{
	switch (type) {
	case PR_TYPE_WRITE_EXCLUSIVE:
	case PR_TYPE_EXCLUSIVE_ACCESS:
	case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
	case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
	case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
	case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
		return core_scsi3_pro_preempt(cmd, type, scope, res_key,
					      sa_res_key, preempt_type);
	default:
		pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
			" Type: 0x%02x\n", (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", type);
		return TCM_INVALID_CDB_FIELD;
	}
}


static sense_reason_t
core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
		u64 sa_res_key, int aptpl, int unreg)
{
	struct se_session *se_sess = cmd->se_sess;
	struct se_device *dev = cmd->se_dev;
	struct se_dev_entry *dest_se_deve = NULL;
	struct se_lun *se_lun = cmd->se_lun, *tmp_lun;
	struct se_node_acl *pr_res_nacl, *pr_reg_nacl, *dest_node_acl = NULL;
	struct se_portal_group *se_tpg, *dest_se_tpg = NULL;
	const struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops;
	struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char *buf;
	const unsigned char *initiator_str;
	char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
	u32 tid_len, tmp_tid_len;
	int new_reg = 0, type, scope, matching_iname;
	sense_reason_t ret;
	unsigned short rtpi;
	unsigned char proto_ident;

	if (!se_sess || !se_lun) {
		pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}

	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
	se_tpg = se_sess->se_tpg;
	tf_ops = se_tpg->se_tpg_tfo;
	/*
	 * Follow logic from spc4r17 Section 5.7.8, Table 50 --
	 *	Register behaviors for a REGISTER AND MOVE service action
	 *
	 * Locate the existing *pr_reg via struct se_node_acl pointers
	 */
	pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
				se_sess);
	if (!pr_reg) {
		pr_err("SPC-3 PR: Unable to locate PR_REGISTERED"
			" *pr_reg for REGISTER_AND_MOVE\n");
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
	}
	/*
	 * The provided reservation key much match the existing reservation key
	 * provided during this initiator's I_T nexus registration.
	 */
	if (res_key != pr_reg->pr_res_key) {
		pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received"
			" res_key: 0x%016Lx does not match existing SA REGISTER"
			" res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key);
		ret = TCM_RESERVATION_CONFLICT;
		goto out_put_pr_reg;
	}
	/*
	 * The service active reservation key needs to be non zero
	 */
	if (!sa_res_key) {
		pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero"
			" sa_res_key\n");
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out_put_pr_reg;
	}

	/*
	 * Determine the Relative Target Port Identifier where the reservation
	 * will be moved to for the TransportID containing SCSI initiator WWN
	 * information.
	 */
	buf = transport_kmap_data_sg(cmd);
	if (!buf) {
		ret = TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
		goto out_put_pr_reg;
	}

	rtpi = get_unaligned_be16(&buf[18]);
	tid_len = get_unaligned_be32(&buf[20]);
	transport_kunmap_data_sg(cmd);
	buf = NULL;

	if ((tid_len + 24) != cmd->data_length) {
		pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header"
			" does not equal CDB data_length: %u\n", tid_len,
			cmd->data_length);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out_put_pr_reg;
	}

	spin_lock(&dev->se_port_lock);
	list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) {
		if (tmp_lun->lun_rtpi != rtpi)
			continue;
		dest_se_tpg = tmp_lun->lun_tpg;
		dest_tf_ops = dest_se_tpg->se_tpg_tfo;
		if (!dest_tf_ops)
			continue;

		atomic_inc_mb(&dest_se_tpg->tpg_pr_ref_count);
		spin_unlock(&dev->se_port_lock);

		if (core_scsi3_tpg_depend_item(dest_se_tpg)) {
			pr_err("core_scsi3_tpg_depend_item() failed"
				" for dest_se_tpg\n");
			atomic_dec_mb(&dest_se_tpg->tpg_pr_ref_count);
			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
			goto out_put_pr_reg;
		}

		spin_lock(&dev->se_port_lock);
		break;
	}
	spin_unlock(&dev->se_port_lock);

	if (!dest_se_tpg || !dest_tf_ops) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
			" fabric ops from Relative Target Port Identifier:"
			" %hu\n", rtpi);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out_put_pr_reg;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf) {
		ret = TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
		goto out_put_pr_reg;
	}
	proto_ident = (buf[24] & 0x0f);

	pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
			" 0x%02x\n", proto_ident);

	if (proto_ident != dest_se_tpg->proto_id) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: Received"
			" proto_ident: 0x%02x does not match ident: 0x%02x"
			" from fabric: %s\n", proto_ident,
			dest_se_tpg->proto_id,
			dest_tf_ops->fabric_name);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}
	initiator_str = target_parse_pr_out_transport_id(dest_se_tpg,
			&buf[24], &tmp_tid_len, &iport_ptr);
	if (!initiator_str) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
			" initiator_str from Transport ID\n");
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	transport_kunmap_data_sg(cmd);
	buf = NULL;

	pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s"
		" %s\n", dest_tf_ops->fabric_name, (iport_ptr != NULL) ?
		"port" : "device", initiator_str, (iport_ptr != NULL) ?
		iport_ptr : "");
	/*
	 * If a PERSISTENT RESERVE OUT command with a REGISTER AND MOVE service
	 * action specifies a TransportID that is the same as the initiator port
	 * of the I_T nexus for the command received, then the command shall
	 * be terminated with CHECK CONDITION status, with the sense key set to
	 * ILLEGAL REQUEST, and the additional sense code set to INVALID FIELD
	 * IN PARAMETER LIST.
	 */
	pr_reg_nacl = pr_reg->pr_reg_nacl;
	matching_iname = (!strcmp(initiator_str,
				  pr_reg_nacl->initiatorname)) ? 1 : 0;
	if (!matching_iname)
		goto after_iport_check;

	if (!iport_ptr || !pr_reg->isid_present_at_reg) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s"
			" matches: %s on received I_T Nexus\n", initiator_str,
			pr_reg_nacl->initiatorname);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}
	if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s %s"
			" matches: %s %s on received I_T Nexus\n",
			initiator_str, iport_ptr, pr_reg_nacl->initiatorname,
			pr_reg->pr_reg_isid);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}
after_iport_check:
	/*
	 * Locate the destination struct se_node_acl from the received Transport ID
	 */
	mutex_lock(&dest_se_tpg->acl_node_mutex);
	dest_node_acl = __core_tpg_get_initiator_node_acl(dest_se_tpg,
				initiator_str);
	if (dest_node_acl)
		atomic_inc_mb(&dest_node_acl->acl_pr_ref_count);
	mutex_unlock(&dest_se_tpg->acl_node_mutex);

	if (!dest_node_acl) {
		pr_err("Unable to locate %s dest_node_acl for"
			" TransportID%s\n", dest_tf_ops->fabric_name,
			initiator_str);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	if (core_scsi3_nodeacl_depend_item(dest_node_acl)) {
		pr_err("core_scsi3_nodeacl_depend_item() for"
			" dest_node_acl\n");
		atomic_dec_mb(&dest_node_acl->acl_pr_ref_count);
		dest_node_acl = NULL;
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	pr_debug("SPC-3 PR REGISTER_AND_MOVE: Found %s dest_node_acl:"
		" %s from TransportID\n", dest_tf_ops->fabric_name,
		dest_node_acl->initiatorname);

	/*
	 * Locate the struct se_dev_entry pointer for the matching RELATIVE TARGET
	 * PORT IDENTIFIER.
	 */
	dest_se_deve = core_get_se_deve_from_rtpi(dest_node_acl, rtpi);
	if (!dest_se_deve) {
		pr_err("Unable to locate %s dest_se_deve from RTPI:"
			" %hu\n",  dest_tf_ops->fabric_name, rtpi);
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}

	if (core_scsi3_lunacl_depend_item(dest_se_deve)) {
		pr_err("core_scsi3_lunacl_depend_item() failed\n");
		kref_put(&dest_se_deve->pr_kref, target_pr_kref_release);
		dest_se_deve = NULL;
		ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
		goto out;
	}

	pr_debug("SPC-3 PR REGISTER_AND_MOVE: Located %s node %s LUN"
		" ACL for dest_se_deve->mapped_lun: %llu\n",
		dest_tf_ops->fabric_name, dest_node_acl->initiatorname,
		dest_se_deve->mapped_lun);

	/*
	 * A persistent reservation needs to already existing in order to
	 * successfully complete the REGISTER_AND_MOVE service action..
	 */
	spin_lock(&dev->dev_reservation_lock);
	pr_res_holder = dev->dev_pr_res_holder;
	if (!pr_res_holder) {
		pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation"
			" currently held\n");
		spin_unlock(&dev->dev_reservation_lock);
		ret = TCM_INVALID_CDB_FIELD;
		goto out;
	}
	/*
	 * The received on I_T Nexus must be the reservation holder.
	 *
	 * From spc4r17 section 5.7.8  Table 50 --
	 * 	Register behaviors for a REGISTER AND MOVE service action
	 */
	if (!is_reservation_holder(pr_res_holder, pr_reg)) {
		pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T"
			" Nexus is not reservation holder\n");
		spin_unlock(&dev->dev_reservation_lock);
		ret = TCM_RESERVATION_CONFLICT;
		goto out;
	}
	/*
	 * From spc4r17 section 5.7.8: registering and moving reservation
	 *
	 * If a PERSISTENT RESERVE OUT command with a REGISTER AND MOVE service
	 * action is received and the established persistent reservation is a
	 * Write Exclusive - All Registrants type or Exclusive Access -
	 * All Registrants type reservation, then the command shall be completed
	 * with RESERVATION CONFLICT status.
	 */
	if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
	    (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
		pr_warn("SPC-3 PR REGISTER_AND_MOVE: Unable to move"
			" reservation for type: %s\n",
			core_scsi3_pr_dump_type(pr_res_holder->pr_res_type));
		spin_unlock(&dev->dev_reservation_lock);
		ret = TCM_RESERVATION_CONFLICT;
		goto out;
	}
	pr_res_nacl = pr_res_holder->pr_reg_nacl;
	/*
	 * b) Ignore the contents of the (received) SCOPE and TYPE fields;
	 */
	type = pr_res_holder->pr_res_type;
	scope = pr_res_holder->pr_res_type;
	/*
	 * c) Associate the reservation key specified in the SERVICE ACTION
	 *    RESERVATION KEY field with the I_T nexus specified as the
	 *    destination of the register and move, where:
	 *    A) The I_T nexus is specified by the TransportID and the
	 *	 RELATIVE TARGET PORT IDENTIFIER field (see 6.14.4); and
	 *    B) Regardless of the TransportID format used, the association for
	 *       the initiator port is based on either the initiator port name
	 *       (see 3.1.71) on SCSI transport protocols where port names are
	 *       required or the initiator port identifier (see 3.1.70) on SCSI
	 *       transport protocols where port names are not required;
	 * d) Register the reservation key specified in the SERVICE ACTION
	 *    RESERVATION KEY field;
	 * e) Retain the reservation key specified in the SERVICE ACTION
	 *    RESERVATION KEY field and associated information;
	 *
	 * Also, It is not an error for a REGISTER AND MOVE service action to
	 * register an I_T nexus that is already registered with the same
	 * reservation key or a different reservation key.
	 */
	dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
					iport_ptr);
	if (!dest_pr_reg) {
		struct se_lun *dest_lun = rcu_dereference_check(dest_se_deve->se_lun,
				kref_read(&dest_se_deve->pr_kref) != 0);

		spin_unlock(&dev->dev_reservation_lock);
		if (core_scsi3_alloc_registration(cmd->se_dev, dest_node_acl,
					dest_lun, dest_se_deve, dest_se_deve->mapped_lun,
					iport_ptr, sa_res_key, 0, aptpl, 2, 1)) {
			ret = TCM_INSUFFICIENT_REGISTRATION_RESOURCES;
			goto out;
		}
		spin_lock(&dev->dev_reservation_lock);
		dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
						iport_ptr);
		new_reg = 1;
	}
	/*
	 * f) Release the persistent reservation for the persistent reservation
	 *    holder (i.e., the I_T nexus on which the
	 */
	__core_scsi3_complete_pro_release(dev, pr_res_nacl,
					  dev->dev_pr_res_holder, 0, 0);
	/*
	 * g) Move the persistent reservation to the specified I_T nexus using
	 *    the same scope and type as the persistent reservation released in
	 *    item f); and
	 */
	dev->dev_pr_res_holder = dest_pr_reg;
	dest_pr_reg->pr_res_holder = 1;
	dest_pr_reg->pr_res_type = type;
	pr_reg->pr_res_scope = scope;
	core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN);
	/*
	 * Increment PRGeneration for existing registrations..
	 */
	if (!new_reg)
		dest_pr_reg->pr_res_generation = pr_tmpl->pr_generation++;
	spin_unlock(&dev->dev_reservation_lock);

	pr_debug("SPC-3 PR [%s] Service Action: REGISTER_AND_MOVE"
		" created new reservation holder TYPE: %s on object RTPI:"
		" %hu  PRGeneration: 0x%08x\n", dest_tf_ops->fabric_name,
		core_scsi3_pr_dump_type(type), rtpi,
		dest_pr_reg->pr_res_generation);
	pr_debug("SPC-3 PR Successfully moved reservation from"
		" %s Fabric Node: %s%s -> %s Fabric Node: %s %s\n",
		tf_ops->fabric_name, pr_reg_nacl->initiatorname,
		i_buf, dest_tf_ops->fabric_name,
		dest_node_acl->initiatorname, (iport_ptr != NULL) ?
		iport_ptr : "");
	/*
	 * It is now safe to release configfs group dependencies for destination
	 * of Transport ID Initiator Device/Port Identifier
	 */
	core_scsi3_lunacl_undepend_item(dest_se_deve);
	core_scsi3_nodeacl_undepend_item(dest_node_acl);
	core_scsi3_tpg_undepend_item(dest_se_tpg);
	/*
	 * h) If the UNREG bit is set to one, unregister (see 5.7.11.3) the I_T
	 * nexus on which PERSISTENT RESERVE OUT command was received.
	 */
	if (unreg) {
		spin_lock(&pr_tmpl->registration_lock);
		__core_scsi3_free_registration(dev, pr_reg, NULL, 1);
		spin_unlock(&pr_tmpl->registration_lock);
	} else
		core_scsi3_put_pr_reg(pr_reg);

	core_scsi3_update_and_write_aptpl(cmd->se_dev, aptpl);

	core_scsi3_put_pr_reg(dest_pr_reg);
	return 0;
out:
	if (buf)
		transport_kunmap_data_sg(cmd);
	if (dest_se_deve)
		core_scsi3_lunacl_undepend_item(dest_se_deve);
	if (dest_node_acl)
		core_scsi3_nodeacl_undepend_item(dest_node_acl);
	core_scsi3_tpg_undepend_item(dest_se_tpg);

out_put_pr_reg:
	core_scsi3_put_pr_reg(pr_reg);
	return ret;
}

/*
 * See spc4r17 section 6.14 Table 170
 */
sense_reason_t
target_scsi3_emulate_pr_out(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	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;
	sense_reason_t ret;

	/*
	 * 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_reservation_flags & DRF_SPC2_RESERVATIONS) {
		pr_err("Received PERSISTENT_RESERVE CDB while legacy"
			" SPC-2 reservation is held, returning"
			" RESERVATION_CONFLICT\n");
		return TCM_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.
	 */
	if (!cmd->se_sess)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	if (cmd->data_length < 24) {
		pr_warn("SPC-PR: Received PR OUT parameter list"
			" length too small: %u\n", cmd->data_length);
		return TCM_PARAMETER_LIST_LENGTH_ERROR;
	}

	/*
	 * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB)
	 */
	sa = (cdb[1] & 0x1f);
	scope = (cdb[2] & 0xf0);
	type = (cdb[2] & 0x0f);

	buf = transport_kmap_data_sg(cmd);
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	/*
	 * From PERSISTENT_RESERVE_OUT parameter list (payload)
	 */
	res_key = get_unaligned_be64(&buf[0]);
	sa_res_key = get_unaligned_be64(&buf[8]);
	/*
	 * REGISTER_AND_MOVE uses a different SA parameter list containing
	 * SCSI TransportIDs.
	 */
	if (sa != PRO_REGISTER_AND_MOVE) {
		spec_i_pt = (buf[20] & 0x08);
		all_tg_pt = (buf[20] & 0x04);
		aptpl = (buf[20] & 0x01);
	} else {
		aptpl = (buf[17] & 0x01);
		unreg = (buf[17] & 0x02);
	}
	/*
	 * If the backend device has been configured to force APTPL metadata
	 * write-out, go ahead and propigate aptpl=1 down now.
	 */
	if (dev->dev_attrib.force_pr_aptpl)
		aptpl = 1;

	transport_kunmap_data_sg(cmd);
	buf = NULL;

	/*
	 * SPEC_I_PT=1 is only valid for Service action: REGISTER
	 */
	if (spec_i_pt && (sa != PRO_REGISTER))
		return TCM_INVALID_PARAMETER_LIST;

	/*
	 * From spc4r17 section 6.14:
	 *
	 * If the SPEC_I_PT bit is set to zero, the service action is not
	 * REGISTER AND MOVE, and the parameter list length is not 24, then
	 * the command shall be terminated with CHECK CONDITION status, with
	 * the sense key set to ILLEGAL REQUEST, and the additional sense
	 * code set to PARAMETER LIST LENGTH ERROR.
	 */
	if (!spec_i_pt && (sa != PRO_REGISTER_AND_MOVE) &&
	    (cmd->data_length != 24)) {
		pr_warn("SPC-PR: Received PR OUT illegal parameter"
			" list length: %u\n", cmd->data_length);
		return TCM_PARAMETER_LIST_LENGTH_ERROR;
	}

	/*
	 * (core_scsi3_emulate_pro_* function parameters
	 * are defined by spc4r17 Table 174:
	 * PERSISTENT_RESERVE_OUT service actions and valid parameters.
	 */
	switch (sa) {
	case PRO_REGISTER:
		ret = core_scsi3_emulate_pro_register(cmd,
			res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, REGISTER);
		break;
	case PRO_RESERVE:
		ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key);
		break;
	case PRO_RELEASE:
		ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key);
		break;
	case PRO_CLEAR:
		ret = core_scsi3_emulate_pro_clear(cmd, res_key);
		break;
	case PRO_PREEMPT:
		ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
					res_key, sa_res_key, PREEMPT);
		break;
	case PRO_PREEMPT_AND_ABORT:
		ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
					res_key, sa_res_key, PREEMPT_AND_ABORT);
		break;
	case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
		ret = core_scsi3_emulate_pro_register(cmd,
			0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, REGISTER_AND_IGNORE_EXISTING_KEY);
		break;
	case PRO_REGISTER_AND_MOVE:
		ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key,
				sa_res_key, aptpl, unreg);
		break;
	default:
		pr_err("Unknown PERSISTENT_RESERVE_OUT service"
			" action: 0x%02x\n", sa);
		return TCM_INVALID_CDB_FIELD;
	}

	if (!ret)
		target_complete_cmd(cmd, GOOD);
	return ret;
}

/*
 * PERSISTENT_RESERVE_IN Service Action READ_KEYS
 *
 * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160
 */
static sense_reason_t
core_scsi3_pri_read_keys(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct t10_pr_registration *pr_reg;
	unsigned char *buf;
	u32 add_len = 0, off = 8;

	if (cmd->data_length < 8) {
		pr_err("PRIN SA READ_KEYS SCSI Data Length: %u"
			" too small\n", cmd->data_length);
		return TCM_INVALID_CDB_FIELD;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	put_unaligned_be32(dev->t10_pr.pr_generation, buf);

	spin_lock(&dev->t10_pr.registration_lock);
	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list,
			pr_reg_list) {
		/*
		 * Check for overflow of 8byte PRI READ_KEYS payload and
		 * next reservation key list descriptor.
		 */
		if (off + 8 <= cmd->data_length) {
			put_unaligned_be64(pr_reg->pr_res_key, &buf[off]);
			off += 8;
		}
		/*
		 * SPC5r17: 6.16.2 READ KEYS service action
		 * The ADDITIONAL LENGTH field indicates the number of bytes in
		 * the Reservation key list. The contents of the ADDITIONAL
		 * LENGTH field are not altered based on the allocation length
		 */
		add_len += 8;
	}
	spin_unlock(&dev->t10_pr.registration_lock);

	put_unaligned_be32(add_len, &buf[4]);

	transport_kunmap_data_sg(cmd);

	return 0;
}

/*
 * PERSISTENT_RESERVE_IN Service Action READ_RESERVATION
 *
 * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162
 */
static sense_reason_t
core_scsi3_pri_read_reservation(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct t10_pr_registration *pr_reg;
	unsigned char *buf;
	u64 pr_res_key;
	u32 add_len = 16; /* Hardcoded to 16 when a reservation is held. */

	if (cmd->data_length < 8) {
		pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
			" too small\n", cmd->data_length);
		return TCM_INVALID_CDB_FIELD;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	put_unaligned_be32(dev->t10_pr.pr_generation, &buf[0]);

	spin_lock(&dev->dev_reservation_lock);
	pr_reg = dev->dev_pr_res_holder;
	if (pr_reg) {
		/*
		 * Set the hardcoded Additional Length
		 */
		put_unaligned_be32(add_len, &buf[4]);

		if (cmd->data_length < 22)
			goto err;

		/*
		 * Set the Reservation key.
		 *
		 * From spc4r17, section 5.7.10:
		 * A persistent reservation holder has its reservation key
		 * returned in the parameter data from a PERSISTENT
		 * RESERVE IN command with READ RESERVATION service action as
		 * follows:
		 * a) For a persistent reservation of the type Write Exclusive
		 *    - All Registrants or Exclusive Access ­ All Regitrants,
		 *      the reservation key shall be set to zero; or
		 * b) For all other persistent reservation types, the
		 *    reservation key shall be set to the registered
		 *    reservation key for the I_T nexus that holds the
		 *    persistent reservation.
		 */
		if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))
			pr_res_key = 0;
		else
			pr_res_key = pr_reg->pr_res_key;

		put_unaligned_be64(pr_res_key, &buf[8]);
		/*
		 * Set the SCOPE and TYPE
		 */
		buf[21] = (pr_reg->pr_res_scope & 0xf0) |
			  (pr_reg->pr_res_type & 0x0f);
	}

err:
	spin_unlock(&dev->dev_reservation_lock);
	transport_kunmap_data_sg(cmd);

	return 0;
}

/*
 * PERSISTENT_RESERVE_IN Service Action REPORT_CAPABILITIES
 *
 * See spc4r17 section 6.13.4 Table 165
 */
static sense_reason_t
core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char *buf;
	u16 add_len = 8; /* Hardcoded to 8. */

	if (cmd->data_length < 6) {
		pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
			" %u too small\n", cmd->data_length);
		return TCM_INVALID_CDB_FIELD;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	put_unaligned_be16(add_len, &buf[0]);
	buf[2] |= 0x10; /* CRH: Compatible Reservation Hanlding bit. */
	buf[2] |= 0x08; /* SIP_C: Specify Initiator Ports Capable bit */
	buf[2] |= 0x04; /* ATP_C: All Target Ports Capable bit */
	buf[2] |= 0x01; /* PTPL_C: Persistence across Target Power Loss bit */
	/*
	 * We are filling in the PERSISTENT RESERVATION TYPE MASK below, so
	 * set the TMV: Task Mask Valid bit.
	 */
	buf[3] |= 0x80;
	/*
	 * Change ALLOW COMMANDs to 0x20 or 0x40 later from Table 166
	 */
	buf[3] |= 0x10; /* ALLOW COMMANDs field 001b */
	/*
	 * PTPL_A: Persistence across Target Power Loss Active bit
	 */
	if (pr_tmpl->pr_aptpl_active)
		buf[3] |= 0x01;
	/*
	 * Setup the PERSISTENT RESERVATION TYPE MASK from Table 167
	 */
	buf[4] |= 0x80; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
	buf[4] |= 0x40; /* PR_TYPE_EXCLUSIVE_ACCESS_REGONLY */
	buf[4] |= 0x20; /* PR_TYPE_WRITE_EXCLUSIVE_REGONLY */
	buf[4] |= 0x08; /* PR_TYPE_EXCLUSIVE_ACCESS */
	buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
	buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */

	transport_kunmap_data_sg(cmd);

	return 0;
}

/*
 * PERSISTENT_RESERVE_IN Service Action READ_FULL_STATUS
 *
 * See spc4r17 section 6.13.5 Table 168 and 169
 */
static sense_reason_t
core_scsi3_pri_read_full_status(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	struct se_node_acl *se_nacl;
	struct se_portal_group *se_tpg;
	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char *buf;
	u32 add_desc_len = 0, add_len = 0;
	u32 off = 8; /* off into first Full Status descriptor */
	int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
	int exp_desc_len, desc_len;
	bool all_reg = false;

	if (cmd->data_length < 8) {
		pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
			" too small\n", cmd->data_length);
		return TCM_INVALID_CDB_FIELD;
	}

	buf = transport_kmap_data_sg(cmd);
	if (!buf)
		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

	put_unaligned_be32(dev->t10_pr.pr_generation, &buf[0]);

	spin_lock(&dev->dev_reservation_lock);
	if (dev->dev_pr_res_holder) {
		struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder;

		if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
		    pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
			all_reg = true;
			pr_res_type = pr_holder->pr_res_type;
			pr_res_scope = pr_holder->pr_res_scope;
		}
	}
	spin_unlock(&dev->dev_reservation_lock);

	spin_lock(&pr_tmpl->registration_lock);
	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
			&pr_tmpl->registration_list, pr_reg_list) {

		se_nacl = pr_reg->pr_reg_nacl;
		se_tpg = pr_reg->pr_reg_nacl->se_tpg;
		add_desc_len = 0;

		atomic_inc_mb(&pr_reg->pr_res_holders);
		spin_unlock(&pr_tmpl->registration_lock);
		/*
		 * Determine expected length of $FABRIC_MOD specific
		 * TransportID full status descriptor..
		 */
		exp_desc_len = target_get_pr_transport_id_len(se_nacl, pr_reg,
					&format_code);
		if (exp_desc_len < 0 ||
		    exp_desc_len + add_len > cmd->data_length) {
			pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
				" out of buffer: %d\n", cmd->data_length);
			spin_lock(&pr_tmpl->registration_lock);
			atomic_dec_mb(&pr_reg->pr_res_holders);
			break;
		}
		/*
		 * Set RESERVATION KEY
		 */
		put_unaligned_be64(pr_reg->pr_res_key, &buf[off]);
		off += 8;
		off += 4; /* Skip Over Reserved area */

		/*
		 * Set ALL_TG_PT bit if PROUT SA REGISTER had this set.
		 */
		if (pr_reg->pr_reg_all_tg_pt)
			buf[off] = 0x02;
		/*
		 * The struct se_lun pointer will be present for the
		 * reservation holder for PR_HOLDER bit.
		 *
		 * Also, if this registration is the reservation
		 * holder or there is an All Registrants reservation
		 * active, fill in SCOPE and TYPE in the next byte.
		 */
		if (pr_reg->pr_res_holder) {
			buf[off++] |= 0x01;
			buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
				     (pr_reg->pr_res_type & 0x0f);
		} else if (all_reg) {
			buf[off++] |= 0x01;
			buf[off++] = (pr_res_scope & 0xf0) |
				     (pr_res_type & 0x0f);
		} else {
			off += 2;
		}

		off += 4; /* Skip over reserved area */
		/*
		 * From spc4r17 6.3.15:
		 *
		 * If the ALL_TG_PT bit set to zero, the RELATIVE TARGET PORT
		 * IDENTIFIER field contains the relative port identifier (see
		 * 3.1.120) of the target port that is part of the I_T nexus
		 * described by this full status descriptor. If the ALL_TG_PT
		 * bit is set to one, the contents of the RELATIVE TARGET PORT
		 * IDENTIFIER field are not defined by this standard.
		 */
		if (!pr_reg->pr_reg_all_tg_pt) {
			u16 sep_rtpi = pr_reg->tg_pt_sep_rtpi;

			put_unaligned_be16(sep_rtpi, &buf[off]);
			off += 2;
		} else
			off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */

		buf[off+4] = se_tpg->proto_id;

		/*
		 * Now, have the $FABRIC_MOD fill in the transport ID.
		 */
		desc_len = target_get_pr_transport_id(se_nacl, pr_reg,
				&format_code, &buf[off+4]);

		spin_lock(&pr_tmpl->registration_lock);
		atomic_dec_mb(&pr_reg->pr_res_holders);

		if (desc_len < 0)
			break;
		/*
		 * Set the ADDITIONAL DESCRIPTOR LENGTH
		 */
		put_unaligned_be32(desc_len, &buf[off]);
		off += 4;
		/*
		 * Size of full desctipor header minus TransportID
		 * containing $FABRIC_MOD specific) initiator device/port
		 * WWN information.
		 *
		 *  See spc4r17 Section 6.13.5 Table 169
		 */
		add_desc_len = (24 + desc_len);

		off += desc_len;
		add_len += add_desc_len;
	}
	spin_unlock(&pr_tmpl->registration_lock);
	/*
	 * Set ADDITIONAL_LENGTH
	 */
	put_unaligned_be32(add_len, &buf[4]);

	transport_kunmap_data_sg(cmd);

	return 0;
}

sense_reason_t
target_scsi3_emulate_pr_in(struct se_cmd *cmd)
{
	sense_reason_t ret;

	/*
	 * 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_reservation_flags & DRF_SPC2_RESERVATIONS) {
		pr_err("Received PERSISTENT_RESERVE CDB while legacy"
			" SPC-2 reservation is held, returning"
			" RESERVATION_CONFLICT\n");
		return TCM_RESERVATION_CONFLICT;
	}

	switch (cmd->t_task_cdb[1] & 0x1f) {
	case PRI_READ_KEYS:
		ret = core_scsi3_pri_read_keys(cmd);
		break;
	case PRI_READ_RESERVATION:
		ret = core_scsi3_pri_read_reservation(cmd);
		break;
	case PRI_REPORT_CAPABILITIES:
		ret = core_scsi3_pri_report_capabilities(cmd);
		break;
	case PRI_READ_FULL_STATUS:
		ret = core_scsi3_pri_read_full_status(cmd);
		break;
	default:
		pr_err("Unknown PERSISTENT_RESERVE_IN service"
			" action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
		return TCM_INVALID_CDB_FIELD;
	}

	if (!ret)
		target_complete_cmd(cmd, GOOD);
	return ret;
}

sense_reason_t
target_check_reservation(struct se_cmd *cmd)
{
	struct se_device *dev = cmd->se_dev;
	sense_reason_t ret;

	if (!cmd->se_sess)
		return 0;
	if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)
		return 0;
	if (!dev->dev_attrib.emulate_pr)
		return 0;
	if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
		return 0;

	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;
}
