// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 * Filename:  target_core_tmr.c
 *
 * This file contains SPC-3 task management infrastructure
 *
 * (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/export.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_alua.h"
#include "target_core_pr.h"

int core_tmr_alloc_req(
	struct se_cmd *se_cmd,
	void *fabric_tmr_ptr,
	u8 function,
	gfp_t gfp_flags)
{
	struct se_tmr_req *tmr;

	tmr = kzalloc(sizeof(struct se_tmr_req), gfp_flags);
	if (!tmr) {
		pr_err("Unable to allocate struct se_tmr_req\n");
		return -ENOMEM;
	}

	se_cmd->se_cmd_flags |= SCF_SCSI_TMR_CDB;
	se_cmd->se_tmr_req = tmr;
	tmr->task_cmd = se_cmd;
	tmr->fabric_tmr_ptr = fabric_tmr_ptr;
	tmr->function = function;
	INIT_LIST_HEAD(&tmr->tmr_list);

	return 0;
}
EXPORT_SYMBOL(core_tmr_alloc_req);

void core_tmr_release_req(struct se_tmr_req *tmr)
{
	kfree(tmr);
}

static int target_check_cdb_and_preempt(struct list_head *list,
		struct se_cmd *cmd)
{
	struct t10_pr_registration *reg;

	if (!list)
		return 0;
	list_for_each_entry(reg, list, pr_reg_abort_list) {
		if (reg->pr_res_key == cmd->pr_res_key)
			return 0;
	}

	return 1;
}

static bool __target_check_io_state(struct se_cmd *se_cmd,
				    struct se_session *tmr_sess, bool tas)
{
	struct se_session *sess = se_cmd->se_sess;

	lockdep_assert_held(&sess->sess_cmd_lock);

	/*
	 * If command already reached CMD_T_COMPLETE state within
	 * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
	 * this se_cmd has been passed to fabric driver and will
	 * not be aborted.
	 *
	 * Otherwise, obtain a local se_cmd->cmd_kref now for TMR
	 * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as
	 * long as se_cmd->cmd_kref is still active unless zero.
	 */
	spin_lock(&se_cmd->t_state_lock);
	if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) {
		pr_debug("Attempted to abort io tag: %llu already complete or"
			" fabric stop, skipping\n", se_cmd->tag);
		spin_unlock(&se_cmd->t_state_lock);
		return false;
	}
	se_cmd->transport_state |= CMD_T_ABORTED;

	if ((tmr_sess != se_cmd->se_sess) && tas)
		se_cmd->transport_state |= CMD_T_TAS;

	spin_unlock(&se_cmd->t_state_lock);

	return kref_get_unless_zero(&se_cmd->cmd_kref);
}

void core_tmr_abort_task(
	struct se_device *dev,
	struct se_tmr_req *tmr,
	struct se_session *se_sess)
{
	LIST_HEAD(aborted_list);
	struct se_cmd *se_cmd, *next;
	unsigned long flags;
	bool rc;
	u64 ref_tag;
	int i;

	for (i = 0; i < dev->queue_cnt; i++) {
		flush_work(&dev->queues[i].sq.work);

		spin_lock_irqsave(&dev->queues[i].lock, flags);
		list_for_each_entry_safe(se_cmd, next, &dev->queues[i].state_list,
					 state_list) {
			if (se_sess != se_cmd->se_sess)
				continue;

			/*
			 * skip task management functions, including
			 * tmr->task_cmd
			 */
			if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
				continue;

			ref_tag = se_cmd->tag;
			if (tmr->ref_task_tag != ref_tag)
				continue;

			pr_err("ABORT_TASK: Found referenced %s task_tag: %llu\n",
			       se_cmd->se_tfo->fabric_name, ref_tag);

			spin_lock(&se_sess->sess_cmd_lock);
			rc = __target_check_io_state(se_cmd, se_sess, 0);
			spin_unlock(&se_sess->sess_cmd_lock);
			if (!rc)
				continue;

			list_move_tail(&se_cmd->state_list, &aborted_list);
			se_cmd->state_active = false;
			spin_unlock_irqrestore(&dev->queues[i].lock, flags);

			if (dev->transport->tmr_notify)
				dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
							   &aborted_list);

			list_del_init(&se_cmd->state_list);
			target_put_cmd_and_wait(se_cmd);

			pr_err("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for ref_tag: %llu\n",
			       ref_tag);
			tmr->response = TMR_FUNCTION_COMPLETE;
			atomic_long_inc(&dev->aborts_complete);
			return;
		}
		spin_unlock_irqrestore(&dev->queues[i].lock, flags);
	}

	if (dev->transport->tmr_notify)
		dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list);

	printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n",
			tmr->ref_task_tag);
	tmr->response = TMR_TASK_DOES_NOT_EXIST;
	atomic_long_inc(&dev->aborts_no_task);
}

static void core_tmr_drain_tmr_list(
	struct se_device *dev,
	struct se_tmr_req *tmr,
	struct list_head *preempt_and_abort_list)
{
	LIST_HEAD(drain_tmr_list);
	struct se_session *sess;
	struct se_tmr_req *tmr_p, *tmr_pp;
	struct se_cmd *cmd;
	unsigned long flags;
	bool rc;
	/*
	 * Release all pending and outgoing TMRs aside from the received
	 * LUN_RESET tmr..
	 */
	spin_lock_irqsave(&dev->se_tmr_lock, flags);
	if (tmr)
		list_del_init(&tmr->tmr_list);
	list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) {
		cmd = tmr_p->task_cmd;
		if (!cmd) {
			pr_err("Unable to locate struct se_cmd for TMR\n");
			continue;
		}
		/*
		 * If this function was called with a valid pr_res_key
		 * parameter (eg: for PROUT PREEMPT_AND_ABORT service action
		 * skip non registration key matching TMRs.
		 */
		if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
			continue;

		sess = cmd->se_sess;
		if (WARN_ON_ONCE(!sess))
			continue;

		spin_lock(&sess->sess_cmd_lock);
		rc = __target_check_io_state(cmd, sess, 0);
		spin_unlock(&sess->sess_cmd_lock);

		if (!rc) {
			printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n");
			continue;
		}

		list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
		tmr_p->tmr_dev = NULL;
	}
	spin_unlock_irqrestore(&dev->se_tmr_lock, flags);

	list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) {
		list_del_init(&tmr_p->tmr_list);
		cmd = tmr_p->task_cmd;

		pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x,"
			" Response: 0x%02x, t_state: %d\n",
			(preempt_and_abort_list) ? "Preempt" : "", tmr_p,
			tmr_p->function, tmr_p->response, cmd->t_state);

		target_put_cmd_and_wait(cmd);
	}
}

/**
 * core_tmr_drain_state_list() - abort SCSI commands associated with a device
 *
 * @dev:       Device for which to abort outstanding SCSI commands.
 * @prout_cmd: Pointer to the SCSI PREEMPT AND ABORT if this function is called
 *             to realize the PREEMPT AND ABORT functionality.
 * @tmr_sess:  Session through which the LUN RESET has been received.
 * @tas:       Task Aborted Status (TAS) bit from the SCSI control mode page.
 *             A quote from SPC-4, paragraph "7.5.10 Control mode page":
 *             "A task aborted status (TAS) bit set to zero specifies that
 *             aborted commands shall be terminated by the device server
 *             without any response to the application client. A TAS bit set
 *             to one specifies that commands aborted by the actions of an I_T
 *             nexus other than the I_T nexus on which the command was
 *             received shall be completed with TASK ABORTED status."
 * @preempt_and_abort_list: For the PREEMPT AND ABORT functionality, a list
 *             with registrations that will be preempted.
 */
static void core_tmr_drain_state_list(
	struct se_device *dev,
	struct se_cmd *prout_cmd,
	struct se_session *tmr_sess,
	bool tas,
	struct list_head *preempt_and_abort_list)
{
	LIST_HEAD(drain_task_list);
	struct se_session *sess;
	struct se_cmd *cmd, *next;
	unsigned long flags;
	int rc, i;

	/*
	 * Complete outstanding commands with TASK_ABORTED SAM status.
	 *
	 * This is following sam4r17, section 5.6 Aborting commands, Table 38
	 * for TMR LUN_RESET:
	 *
	 * a) "Yes" indicates that each command that is aborted on an I_T nexus
	 * other than the one that caused the SCSI device condition is
	 * completed with TASK ABORTED status, if the TAS bit is set to one in
	 * the Control mode page (see SPC-4). "No" indicates that no status is
	 * returned for aborted commands.
	 *
	 * d) If the logical unit reset is caused by a particular I_T nexus
	 * (e.g., by a LOGICAL UNIT RESET task management function), then "yes"
	 * (TASK_ABORTED status) applies.
	 *
	 * Otherwise (e.g., if triggered by a hard reset), "no"
	 * (no TASK_ABORTED SAM status) applies.
	 *
	 * Note that this seems to be independent of TAS (Task Aborted Status)
	 * in the Control Mode Page.
	 */
	for (i = 0; i < dev->queue_cnt; i++) {
		flush_work(&dev->queues[i].sq.work);

		spin_lock_irqsave(&dev->queues[i].lock, flags);
		list_for_each_entry_safe(cmd, next, &dev->queues[i].state_list,
					 state_list) {
			/*
			 * For PREEMPT_AND_ABORT usage, only process commands
			 * with a matching reservation key.
			 */
			if (target_check_cdb_and_preempt(preempt_and_abort_list,
							 cmd))
				continue;

			/*
			 * Not aborting PROUT PREEMPT_AND_ABORT CDB..
			 */
			if (prout_cmd == cmd)
				continue;

			sess = cmd->se_sess;
			if (WARN_ON_ONCE(!sess))
				continue;

			spin_lock(&sess->sess_cmd_lock);
			rc = __target_check_io_state(cmd, tmr_sess, tas);
			spin_unlock(&sess->sess_cmd_lock);
			if (!rc)
				continue;

			list_move_tail(&cmd->state_list, &drain_task_list);
			cmd->state_active = false;
		}
		spin_unlock_irqrestore(&dev->queues[i].lock, flags);
	}

	if (dev->transport->tmr_notify)
		dev->transport->tmr_notify(dev, preempt_and_abort_list ?
					   TMR_LUN_RESET_PRO : TMR_LUN_RESET,
					   &drain_task_list);

	while (!list_empty(&drain_task_list)) {
		cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
		list_del_init(&cmd->state_list);

		target_show_cmd("LUN_RESET: ", cmd);
		pr_debug("LUN_RESET: ITT[0x%08llx] - %s pr_res_key: 0x%016Lx\n",
			 cmd->tag, (preempt_and_abort_list) ? "preempt" : "",
			 cmd->pr_res_key);

		target_put_cmd_and_wait(cmd);
	}
}

int core_tmr_lun_reset(
        struct se_device *dev,
        struct se_tmr_req *tmr,
        struct list_head *preempt_and_abort_list,
        struct se_cmd *prout_cmd)
{
	struct se_node_acl *tmr_nacl = NULL;
	struct se_portal_group *tmr_tpg = NULL;
	struct se_session *tmr_sess = NULL;
	bool tas;
        /*
	 * TASK_ABORTED status bit, this is configurable via ConfigFS
	 * struct se_device attributes.  spc4r17 section 7.4.6 Control mode page
	 *
	 * A task aborted status (TAS) bit set to zero specifies that aborted
	 * tasks shall be terminated by the device server without any response
	 * to the application client. A TAS bit set to one specifies that tasks
	 * aborted by the actions of an I_T nexus other than the I_T nexus on
	 * which the command was received shall be completed with TASK ABORTED
	 * status (see SAM-4).
	 */
	tas = dev->dev_attrib.emulate_tas;
	/*
	 * Determine if this se_tmr is coming from a $FABRIC_MOD
	 * or struct se_device passthrough..
	 */
	if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) {
		tmr_sess = tmr->task_cmd->se_sess;
		tmr_nacl = tmr_sess->se_node_acl;
		tmr_tpg = tmr_sess->se_tpg;
		if (tmr_nacl && tmr_tpg) {
			pr_debug("LUN_RESET: TMR caller fabric: %s"
				" initiator port %s\n",
				tmr_tpg->se_tpg_tfo->fabric_name,
				tmr_nacl->initiatorname);
		}
	}
	pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n",
		(preempt_and_abort_list) ? "Preempt" : "TMR",
		dev->transport->name, tas);

	core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
	core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
				preempt_and_abort_list);

	/*
	 * Clear any legacy SPC-2 reservation when called during
	 * LOGICAL UNIT RESET
	 */
	if (!preempt_and_abort_list &&
	     (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) {
		spin_lock(&dev->dev_reservation_lock);
		dev->reservation_holder = NULL;
		dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
		spin_unlock(&dev->dev_reservation_lock);
		pr_debug("LUN_RESET: SCSI-2 Released reservation\n");
	}

	atomic_long_inc(&dev->num_resets);

	pr_debug("LUN_RESET: %s for [%s] Complete\n",
			(preempt_and_abort_list) ? "Preempt" : "TMR",
			dev->transport->name);
	return 0;
}

