diff mbox series

[RFC,46/48] target: cluster: implement LUN reset in DLM cluster

Message ID 20220803162857.27770-47-d.bogdanov@yadro.com
State New
Headers show
Series Target cluster implementation over DLM | expand

Commit Message

Dmitry Bogdanov March 11, 2022, 9:30 a.m. UTC
Since LUN RESET clears SCSI2 Reservation (cluster wide data of
persistence reservation status) make LUN RESET just one of reasons to
update the Persistence Reservation status as well as Service Actions of
PR OUT.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/target/target_cluster_dlm.c   | 31 ++++++++++++++++++++++++++-
 drivers/target/target_core_device.c   |  1 +
 drivers/target/target_core_internal.h |  1 -
 include/target/target_core_base.h     |  2 +-
 4 files changed, 32 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/target/target_cluster_dlm.c b/drivers/target/target_cluster_dlm.c
index 91f8ffc7ad2f..546e28062b8f 100644
--- a/drivers/target/target_cluster_dlm.c
+++ b/drivers/target/target_cluster_dlm.c
@@ -99,6 +99,9 @@  struct async_group {
 	struct completion compl;
 };
 
+#define PR_SYNC_REASON_RESERVE	10
+#define PR_SYNC_REASON_RESET	11
+
 static void target_pr_sync_cb(void *arg);
 static void target_nodeleft_cb(void *arg, int nodeid);
 static int pr_reg_realloc(struct target_cluster_data *cluster_data,
@@ -842,6 +845,15 @@  static void target_pr_sync_cb(void *arg)
 					pr_reg_res_holder);
 	}
 
+	if (pr_data.pro_sa == PR_SYNC_REASON_RESET) {
+		core_local_lun_reset(dev, NULL, NULL, NULL);
+
+		target_dev_ua_allocate(dev, 0x29,
+				ASCQ_29H_BUS_DEVICE_RESET_FUNCTION_OCCURRED);
+
+		atomic_long_inc(&dev->num_resets);
+	}
+
 	core_scsi3_update_and_write_aptpl(dev, dev->t10_pr.pr_aptpl_active);
 
 done:
@@ -863,7 +875,23 @@  target_spc2_reserve(struct se_device *dev, struct se_session *sess)
 		cluster_data->reserved_node_id = 0;
 	}
 
-	target_pr_sync_dlm(dev, -1);
+	target_pr_sync_dlm(dev, PR_SYNC_REASON_RESERVE);
+	target_pr_unlock_dlm(dev);
+}
+
+static void
+target_dlm_lun_reset(struct se_device *dev)
+{
+	struct target_cluster_data *cluster_data = dev->cluster_data;
+
+	target_pr_lock_dlm(dev);
+	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) {
+		target_release_reservation(dev);
+		cluster_data->reserved_node_id = 0;
+		pr_debug("LUN_RESET: SCSI-2 Released reservation\n");
+	}
+
+	target_pr_sync_dlm(dev, PR_SYNC_REASON_RESET);
 	target_pr_unlock_dlm(dev);
 }
 
@@ -894,6 +922,7 @@  const struct target_cluster_ops dlm_cluster_ops = {
 	.pr_unlock = target_pr_unlock_dlm,
 	.pr_sync = target_pr_sync_dlm,
 	.reserve = target_spc2_reserve,
+	.reset = target_dlm_lun_reset,
 };
 
 static int __init target_cluster_dlm_module_init(void)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 7d0d889961c2..6fe9f40b86f5 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -375,6 +375,7 @@  void target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq)
 	}
 	spin_unlock(&dev->se_port_lock);
 }
+EXPORT_SYMBOL(target_dev_ua_allocate);
 
 static void
 target_luns_data_has_changed(struct se_node_acl *nacl, struct se_dev_entry *new,
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index fc7c2a9d9507..7c495dddcb4b 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -93,7 +93,6 @@  int	target_configure_device(struct se_device *dev);
 void	target_free_device(struct se_device *);
 int	target_for_each_device(int (*fn)(struct se_device *dev, void *data),
 			       void *data);
-void	target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq);
 
 /* target_core_configfs.c */
 extern struct configfs_item_operations target_core_dev_item_ops;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index c8900da705b6..4dad7837f603 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -1013,6 +1013,6 @@  int target_cmp_pr_transport_id(struct t10_pr_registration *pr_reg,
 void	target_pr_kref_release(struct kref *kref);
 void	core_local_lun_reset(struct se_device *swc, struct se_tmr_req *tmr,
 		struct list_head *preempt_and_abort_list, struct se_cmd *prout_cmd);
-
+void	target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq);
 
 #endif /* TARGET_CORE_BASE_H */