All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Bogdanov <d.bogdanov@yadro.com>
To: Martin Petersen <martin.petersen@oracle.com>,
	<target-devel@vger.kernel.org>
Cc: <linux-scsi@vger.kernel.org>, <linux@yadro.com>,
	Dmitry Bogdanov <d.bogdanov@yadro.com>
Subject: [RFC PATCH 43/48] target: cluster: allocate UAs on PR sync
Date: Mon, 28 Feb 2022 13:37:58 +0300	[thread overview]
Message-ID: <20220803162857.27770-44-d.bogdanov@yadro.com> (raw)
In-Reply-To: <20220803162857.27770-1-d.bogdanov@yadro.com>

Establish Unit Attention condition on the peer nodes in the cluster on
PR OUT commands according to SPC-4.
Pass PR OUT Service Action to pr_sync to allow peer nodes to know the
reason of the update of PR state.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/target/target_cluster_dlm.c | 115 +++++++++++++++++++++++++++-
 drivers/target/target_core_device.c |   7 +-
 drivers/target/target_core_pr.c     |   2 +-
 drivers/target/target_core_ua.c     |   1 +
 include/target/target_core_base.h   |   2 +-
 5 files changed, 121 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_cluster_dlm.c b/drivers/target/target_cluster_dlm.c
index 4c4d337e6a1a..cb44f6c0f0ac 100644
--- a/drivers/target/target_cluster_dlm.c
+++ b/drivers/target/target_cluster_dlm.c
@@ -7,6 +7,7 @@
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
 #include <target/target_core_backend.h>
+#include "target_core_ua.h"
 #include "target_core_pr.h"
 
 #include "dlm_ckv.h"
@@ -78,7 +79,8 @@ struct pr_lvb {
 	u8	pr_type;
 	u8	pr_scope;
 	u8	pr_aptpl;
-	u8	reserved[3];
+	u8	pro_sa;
+	u8	reserved[2];
 	u32	reserved_by_nodeid;
 };
 
@@ -314,7 +316,7 @@ static int pr_reg_realloc(struct target_cluster_data *cluster_data,
 	return res;
 }
 
-static int target_pr_sync_dlm(struct se_device *dev)
+static int target_pr_sync_dlm(struct se_device *dev, u8 pro_sa)
 {
 	struct target_cluster_data *cluster_data = dev->cluster_data;
 	struct t10_pr_registration *pr_reg;
@@ -328,6 +330,7 @@ static int target_pr_sync_dlm(struct se_device *dev)
 
 	pr_data.version = 1;
 	pr_data.pr_generation = atomic_read(&dev->t10_pr.pr_generation);
+	pr_data.pro_sa = pro_sa;
 	pr_data.nr_registrants = target_get_nr_registrants(dev);
 	pr_data.pr_is_set = !!dev->dev_pr_res_holder;
 	pr_data.pr_aptpl = dev->t10_pr.pr_aptpl_active;
@@ -546,6 +549,19 @@ target_create_pr_reg(struct se_device *dev,
 	return NULL;
 }
 
+static void target_allocate_pr_ua(struct se_device *dev, u8 asc)
+{
+	struct t10_pr_registration *pr_reg;
+
+	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, pr_reg_list) {
+		target_ua_allocate_lun(
+			pr_reg->pr_reg_nacl,
+			pr_reg->pr_res_mapped_lun,
+			0x2A,
+			asc);
+	}
+}
+
 static void target_pr_sync_cb(void *arg)
 {
 	struct se_device *dev = arg;
@@ -558,6 +574,9 @@ static void target_pr_sync_cb(void *arg)
 	struct async_group grp;
 	struct pr_lvb pr_data;
 	bool res_to_delete = false;
+	struct se_node_acl *pr_reg_nacl;
+	u64 pr_res_mapped_lun;
+	bool reg_deleted = false;
 	bool was_held;
 	u8 was_type;
 	u8 was_scope;
@@ -656,10 +675,41 @@ static void target_pr_sync_cb(void *arg)
 	/* deregister obsolete entries */
 	list_for_each_entry_safe(pr_reg, pr_reg_tmp, &to_be_deleted_list,
 			pr_reg_list) {
+		reg_deleted = true;
+		pr_reg_nacl = pr_reg->pr_reg_nacl;
+		pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
+
 		if (dev->dev_pr_res_holder != pr_reg)
 			__core_scsi3_free_registration(dev, pr_reg, NULL, 0);
 		else
 			res_to_delete = true;
+
+		switch (pr_data.pro_sa) {
+		case PRO_CLEAR:
+			/*
+			 * 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
+			 */
+			target_ua_allocate_lun(pr_reg_nacl,
+					pr_res_mapped_lun, 0x2A,
+					ASCQ_2AH_RESERVATIONS_PREEMPTED);
+			break;
+		case PRO_PREEMPT_AND_ABORT:
+		case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
+			/*
+			 * 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);
+			break;
+		}
 	}
 	spin_unlock(&dev->t10_pr.registration_lock);
 
@@ -677,6 +727,65 @@ static void target_pr_sync_cb(void *arg)
 			pr_reg_res_holder = pr_reg;
 	}
 
+	switch (pr_data.pro_sa) {
+	case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
+	case PRO_REGISTER:
+		/*
+		 * If the I_T nexus is the reservation holder and the persistent
+		 * reservation is of a type other than all registrants, then
+		 * the device server shall also release the persistent reservation
+		 *
+		 * 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 (reg_deleted && was_held &&
+		    (was_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY ||
+		     was_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) {
+			target_allocate_pr_ua(dev,
+				ASCQ_2AH_RESERVATIONS_RELEASED);
+		}
+		break;
+	case PRO_RELEASE:
+		/*
+		 * if the released persistent reservation is either a registrants
+		 * only type or an all registrants type persistent reservation,
+		 * then the device server shall establish a unit attention
+		 * condition for the initiator port associated with every
+		 * registered 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
+		 */
+		if ((was_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
+		    (was_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
+		    (was_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
+		    (was_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
+			target_allocate_pr_ua(dev,
+				ASCQ_2AH_RESERVATIONS_RELEASED);
+		}
+		break;
+	case PRO_PREEMPT:
+	case PRO_PREEMPT_AND_ABORT:
+		/*
+		 * 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. I
+		 */
+		if (pr_prev_res_holder && pr_reg_res_holder &&
+		    pr_prev_res_holder != pr_reg_res_holder &&
+		    (was_type != pr_reg_res_holder->pr_res_type ||
+		     was_scope != pr_reg_res_holder->pr_res_scope))
+			target_allocate_pr_ua(dev, ASCQ_2AH_RESERVATIONS_RELEASED);
+		break;
+	}
+
 	/* update general data */
 	atomic_set(&dev->t10_pr.pr_generation, pr_data.pr_generation);
 	dev->t10_pr.pr_aptpl_active = pr_data.pr_aptpl;
@@ -741,7 +850,7 @@ target_spc2_reserve(struct se_device *dev, struct se_session *sess)
 		cluster_data->reserved_node_id = 0;
 	}
 
-	target_pr_sync_dlm(dev);
+	target_pr_sync_dlm(dev, -1);
 	target_pr_unlock_dlm(dev);
 }
 
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9f01a28ef72f..4f36d12d2213 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -788,6 +788,11 @@ int target_dummy_nodlm(struct se_device *dev)
 	return 0;
 }
 
+int target_prsync_nodlm(struct se_device *dev, u8 pro_sa)
+{
+	return 0;
+}
+
 static void target_reserve2_nodlm(struct se_device *dev, struct se_session *sess)
 {
 	if (sess) {
@@ -806,7 +811,7 @@ const struct target_cluster_ops nodlm_cluster_ops = {
 	.caw_unlock = target_caw_unlock_nodlm,
 	.pr_lock = target_dummy_nodlm,
 	.pr_unlock = target_dummy_nodlm,
-	.pr_sync = target_dummy_nodlm,
+	.pr_sync = target_prsync_nodlm,
 	.reserve = target_reserve2_nodlm,
 };
 
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 930f0bebd75d..fd89647c5ac7 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -3624,7 +3624,7 @@ target_scsi3_emulate_pr_out(struct se_cmd *cmd)
 	}
 
 	if (!ret)
-		dev->cl_ops->pr_sync(dev);
+		dev->cl_ops->pr_sync(dev, sa);
 	dev->cl_ops->pr_unlock(dev);
 
 	if (!ret)
diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c
index 4276690fb6cb..68a7339611f3 100644
--- a/drivers/target/target_core_ua.c
+++ b/drivers/target/target_core_ua.c
@@ -171,6 +171,7 @@ void target_ua_allocate_lun(struct se_node_acl *nacl,
 	core_scsi3_ua_allocate(deve, asc, ascq);
 	rcu_read_unlock();
 }
+EXPORT_SYMBOL(target_ua_allocate_lun);
 
 void core_scsi3_ua_release_all(
 	struct se_dev_entry *deve)
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index c49ddf0828f6..6c99fb4aa151 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -789,7 +789,7 @@ struct target_cluster_ops {
 	int (*caw_unlock)(struct se_device *dev, void *lock);
 	int (*pr_lock)(struct se_device *dev);
 	int (*pr_unlock)(struct se_device *dev);
-	int (*pr_sync)(struct se_device *dev);
+	int (*pr_sync)(struct se_device *dev, u8 pro_sa);
 	void (*reserve)(struct se_device *dev, struct se_session *sess);
 };
 
-- 
2.25.1


  parent reply	other threads:[~2022-08-03 16:31 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-03 16:04 [RFC PATCH 00/48] Target cluster implementation over DLM Dmitry Bogdanov
2019-12-21  0:53 ` [RFC PATCH 07/48] scsi: target/core: Add common port attributes Dmitry Bogdanov
2019-12-21 23:45 ` [RFC PATCH 05/48] scsi: target/core: Use RTPI from target port Dmitry Bogdanov
2019-12-21 23:49 ` [RFC PATCH 06/48] scsi: target/core: Drop device-based RTPI Dmitry Bogdanov
2020-04-04 10:48 ` [RFC PATCH 01/48] scsi: target/core: Add a way to hide a port group Dmitry Bogdanov
2020-04-20  0:18 ` [RFC PATCH 02/48] scsi: target/core: Set MULTIP bit for se_device with multiple ports Dmitry Bogdanov
2020-04-20 17:20 ` [RFC PATCH 03/48] scsi: target/core: Add cleanup sequence in core_tpg_register() Dmitry Bogdanov
2020-04-20 17:57 ` [RFC PATCH 04/48] scsi: target/core: Add RTPI field to target port Dmitry Bogdanov
2020-04-21 14:00 ` [RFC PATCH 08/48] scsi: target/core: Add RTPI attribute for " Dmitry Bogdanov
2020-04-30 14:16 ` [RFC PATCH 10/48] scsi: target/core: Unlock PR generation bump Dmitry Bogdanov
2021-02-25 12:18 ` [RFC PATCH 09/48] target: core: check RTPI uniquity for enabled TPG Dmitry Bogdanov
2021-11-17 11:12 ` [RFC PATCH 36/48] target: cluster: introduce cluster ops Dmitry Bogdanov
2021-11-18  7:52 ` [RFC PATCH 31/48] dlm_ckv: introduce DLM cluster key-value storage Dmitry Bogdanov
2021-11-22 17:07 ` [RFC PATCH 32/48] dlm_ckv: add notification service Dmitry Bogdanov
2021-11-22 17:12 ` [RFC PATCH 33/48] dlm_ckv: add key-value storage service Dmitry Bogdanov
2021-11-29  9:00 ` [RFC PATCH 38/48] target: cluster: store PR data in DLM cluster Dmitry Bogdanov
2021-12-01 15:42 ` [RFC PATCH 15/48] target: core: remove unused variable in se_dev_entry Dmitry Bogdanov
2021-12-06 10:56 ` [RFC PATCH 14/48] target: core: new key must be used for moved PR Dmitry Bogdanov
2021-12-06 13:39 ` [RFC PATCH 39/48] target: cluster: read PR data from cluster Dmitry Bogdanov
2021-12-07  9:47 ` [RFC PATCH 35/48] target: add virtual remote target Dmitry Bogdanov
2021-12-10 12:43 ` [RFC PATCH 17/48] target: core: make some functions public Dmitry Bogdanov
2021-12-13 18:58 ` [RFC PATCH 18/48] target: core: proper clear reservation on LUN RESET Dmitry Bogdanov
2021-12-13 19:15 ` [RFC PATCH 19/48] target: core: remove superfluous checks Dmitry Bogdanov
2021-12-13 19:20 ` [RFC PATCH 20/48] target: core: proper check of SCSI-2 reservation Dmitry Bogdanov
2021-12-13 19:28 ` [RFC PATCH 21/48] target: core: checks against peer node SCSI2 reservation Dmitry Bogdanov
2021-12-16 10:20 ` [RFC PATCH 42/48] target: cluster: sync SPC-2 reservations Dmitry Bogdanov
2021-12-17  9:27 ` [RFC PATCH 41/48] target: cluster: sync-up PR data on cluster join Dmitry Bogdanov
2021-12-22 12:38 ` [RFC PATCH 34/48] dlm_ckv: add KV get/set async API Dmitry Bogdanov
2021-12-24  9:45 ` [RFC PATCH 16/48] target: core: undepend PR registrant of nacl Dmitry Bogdanov
2021-12-24  9:52 ` [RFC PATCH 40/48] target: cluster: sync PR for dynamic acls Dmitry Bogdanov
2022-02-28 10:37 ` Dmitry Bogdanov [this message]
2022-03-02  7:13 ` [RFC PATCH 12/48] target: core: fix memory leak in preempt_and_abort Dmitry Bogdanov
2022-03-04 10:38 ` [RFC PATCH 11/48] target: core: fix preempt and abort for allreg res Dmitry Bogdanov
2022-03-04 10:44 ` [RFC PATCH 13/48] target: core: abort all preempted regs if requested Dmitry Bogdanov
2022-03-04 12:35 ` [RFC PATCH 44/48] target: cluster: support PR OUT preempt and abort Dmitry Bogdanov
2022-03-11  8:11 ` [RFC PATCH 22/48] target: core: UA on all luns after reset Dmitry Bogdanov
2022-03-11  8:33 ` [RFC PATCH 23/48] target: core: refactor LUN_RESET code Dmitry Bogdanov
2022-03-11  8:40 ` [RFC PATCH 45/48] target: cluster: add reset cluster function Dmitry Bogdanov
2022-03-11  9:30 ` [RFC PATCH 46/48] target: cluster: implement LUN reset in DLM cluster Dmitry Bogdanov
2022-03-25  6:35 ` [RFC PATCH 47/48] target: cluster: split cluster sync function Dmitry Bogdanov
2022-03-25  7:58 ` [RFC PATCH 48/48] target: cluster: request data on initial sync Dmitry Bogdanov
2022-06-21 13:05 ` [RFC PATCH 24/48] target: core: pr: use RTPI in APTPL Dmitry Bogdanov
2022-06-22 10:25 ` [RFC PATCH 26/48] target: core: pr: remove se_tpg from pr_reg Dmitry Bogdanov
2022-06-29  7:50 ` [RFC PATCH 27/48] target: core: fix parsing PR OUT TID Dmitry Bogdanov
2022-06-29 10:06 ` [RFC PATCH 28/48] target: core: add function to compare TransportID Dmitry Bogdanov
2022-06-30 11:11 ` [RFC PATCH 29/48] target: core: store proto_id in APTPL Dmitry Bogdanov
2022-07-01  7:26 ` [RFC PATCH 30/48] target: core: rethink APTPL registrations Dmitry Bogdanov
2022-07-22 14:59 ` [RFC PATCH 37/48] target: cluster: introduce dlm cluster Dmitry Bogdanov
2022-07-27 16:21 ` [RFC PATCH 25/48] target: core: pr: have Transport ID stored Dmitry Bogdanov
2022-08-03 17:36 ` [RFC PATCH 00/48] Target cluster implementation over DLM Mike Christie
2022-08-04 11:01   ` Dmitry Bogdanov
2022-08-05 20:01 [RFC PATCH 27/48] target: core: fix parsing PR OUT TID kernel test robot
2022-08-08 10:31 ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220803162857.27770-44-d.bogdanov@yadro.com \
    --to=d.bogdanov@yadro.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux@yadro.com \
    --cc=martin.petersen@oracle.com \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.