diff mbox series

[RFC,47/48] target: cluster: split cluster sync function

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

Commit Message

Dmitry Bogdanov March 25, 2022, 6:35 a.m. UTC
Split cluster sync function to two parts:
1. Read cluster data.
2. Apply cluster data.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/target/target_cluster_dlm.c | 117 ++++++++++++++++++----------
 1 file changed, 74 insertions(+), 43 deletions(-)
diff mbox series

Patch

diff --git a/drivers/target/target_cluster_dlm.c b/drivers/target/target_cluster_dlm.c
index 546e28062b8f..ff0c207be141 100644
--- a/drivers/target/target_cluster_dlm.c
+++ b/drivers/target/target_cluster_dlm.c
@@ -565,61 +565,53 @@  static void target_allocate_pr_ua(struct se_device *dev, u8 asc)
 	}
 }
 
-static void target_pr_sync_cb(void *arg)
+static int target_dlm_read_cluster_data(
+	struct se_device *dev,
+	struct pr_lvb *pr_data,
+	struct pr_reg_lvb **pr_reg_datap)
 {
-	struct se_device *dev = arg;
 	struct target_cluster_data *cluster_data = dev->cluster_data;
-	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
-	struct t10_pr_registration *pr_reg_res_holder = NULL;
-	struct t10_pr_registration *pr_prev_res_holder = NULL;
 	struct pr_reg_lvb *pr_reg_data = NULL;
-	LIST_HEAD(to_be_deleted_list);
-	LIST_HEAD(preempt_and_abort_list);
 	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;
-	bool found;
+	int res = 0;
 	int i = 0;
-	int res;
 
-	res = dlm_ckv_get(cluster_data->pr_data, (char *)&pr_data, sizeof(pr_data));
+	res = dlm_ckv_get(cluster_data->pr_data, (char *)pr_data,
+			  sizeof(struct pr_lvb));
 	if (res)
 		goto done;
 
-	if (!pr_data.version) {
+	if (!pr_data->version) {
 		pr_info("TARGET_CORE[%d]: PR data from cluster is invalid\n",
 			dev->dev_index);
 		goto done;
 	}
 
-	pr_reg_data = kzalloc(sizeof(struct pr_reg_lvb) * pr_data.nr_registrants,
+	if (pr_data->nr_registrants == 0)
+		goto done;
+
+	*pr_reg_datap = kzalloc(sizeof(struct pr_reg_lvb) * pr_data->nr_registrants,
 			    GFP_KERNEL);
+	pr_reg_data = *pr_reg_datap;
 	if (!pr_reg_data) {
 		res = -ENOMEM;
 		goto done;
 	}
 
-	res = pr_reg_realloc(cluster_data, pr_data.nr_registrants);
+	res = pr_reg_realloc(cluster_data, pr_data->nr_registrants);
 	if (res)
 		goto done;
 
-	if (pr_data.nr_registrants == 0)
-		goto skip_pr_reg;
-
 	refcount_set(&grp.pending, 1); /* 1 for a loop */
 	atomic_set(&grp.status, 0);
 	init_completion(&grp.compl);
 
-	for (i = 0; i < pr_data.nr_registrants; ++i) {
+	for (i = 0; i < pr_data->nr_registrants; ++i) {
 		refcount_inc(&grp.pending);
-		res = dlm_ckv_get_async(cluster_data->pr_reg_kv[i], (char *)(pr_reg_data + i),
-				sizeof(struct pr_reg_lvb), group_compl_cb, &grp);
+		res = dlm_ckv_get_async(cluster_data->pr_reg_kv[i],
+					(char *)(pr_reg_data + i),
+					sizeof(struct pr_reg_lvb),
+					group_compl_cb, &grp);
 		if (res) {
 			refcount_dec(&grp.pending);
 			break;
@@ -639,7 +631,33 @@  static void target_pr_sync_cb(void *arg)
 		goto done;
 	}
 
-skip_pr_reg:
+done:
+	if (res)
+		kfree(pr_reg_data);
+	return res;
+}
+
+static void target_dlm_apply_cluster_data(
+	struct se_device *dev,
+	struct pr_lvb *pr_data,
+	struct pr_reg_lvb *pr_reg_data)
+{
+	struct target_cluster_data *cluster_data = dev->cluster_data;
+	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
+	struct t10_pr_registration *pr_reg_res_holder = NULL;
+	struct t10_pr_registration *pr_prev_res_holder = NULL;
+	LIST_HEAD(to_be_deleted_list);
+	LIST_HEAD(preempt_and_abort_list);
+	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;
+	bool found;
+	int i = 0;
+
 	/*
 	 * Update existing registrations
 	 */
@@ -656,7 +674,7 @@  static void target_pr_sync_cb(void *arg)
 				 pr_reg_list) {
 		found = false;
 
-		for (i = 0; i < pr_data.nr_registrants; ++i) {
+		for (i = 0; i < pr_data->nr_registrants; ++i) {
 			if (!pr_reg_data[i].version)
 				continue;
 
@@ -665,7 +683,7 @@  static void target_pr_sync_cb(void *arg)
 				found = true;
 				/* mark existing registrants */
 				pr_reg_data[i].version = 0;
-				target_update_pr_reg(dev, pr_reg, &pr_data,
+				target_update_pr_reg(dev, pr_reg, pr_data,
 						     &pr_reg_data[i],
 						     &pr_reg_res_holder);
 				break;
@@ -685,12 +703,12 @@  static void target_pr_sync_cb(void *arg)
 
 		if (dev->dev_pr_res_holder != pr_reg)
 			__core_scsi3_free_registration(dev, pr_reg,
-				(pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) ?
+				(pr_data->pro_sa == PRO_PREEMPT_AND_ABORT) ?
 				&preempt_and_abort_list : NULL, 0);
 		else
 			res_to_delete = true;
 
-		switch (pr_data.pro_sa) {
+		switch (pr_data->pro_sa) {
 		case PRO_CLEAR:
 			/*
 			 * establish a unit attention condition for the initiator
@@ -720,12 +738,12 @@  static void target_pr_sync_cb(void *arg)
 	spin_unlock(&dev->t10_pr.registration_lock);
 
 	/* register new entries */
-	for (i = 0; i < pr_data.nr_registrants; ++i) {
+	for (i = 0; i < pr_data->nr_registrants; ++i) {
 		/* skip existing registrants */
 		if (!pr_reg_data[i].version)
 			continue;
 
-		pr_reg = target_create_pr_reg(dev, &pr_data, &pr_reg_data[i]);
+		pr_reg = target_create_pr_reg(dev, pr_data, &pr_reg_data[i]);
 		if (!pr_reg)
 			pr_err("TARGET_CORE[%d]: can not create new registration\n",
 				dev->dev_index);
@@ -733,7 +751,7 @@  static void target_pr_sync_cb(void *arg)
 			pr_reg_res_holder = pr_reg;
 	}
 
-	switch (pr_data.pro_sa) {
+	switch (pr_data->pro_sa) {
 	case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
 	case PRO_REGISTER:
 		/*
@@ -793,11 +811,11 @@  static void target_pr_sync_cb(void *arg)
 	}
 
 	/* update general data */
-	atomic_set(&dev->t10_pr.pr_generation, pr_data.pr_generation);
-	dev->t10_pr.pr_aptpl_active = pr_data.pr_aptpl;
+	atomic_set(&dev->t10_pr.pr_generation, pr_data->pr_generation);
+	dev->t10_pr.pr_aptpl_active = pr_data->pr_aptpl;
 
 	/* update SPC-2 reservation */
-	cluster_data->reserved_node_id = pr_data.reserved_by_nodeid;
+	cluster_data->reserved_node_id = pr_data->reserved_by_nodeid;
 	spin_lock(&dev->dev_reservation_lock);
 	if (cluster_data->reserved_node_id == cluster_data->local_nodeid &&
 	    dev->reservation_holder == NULL) {
@@ -826,18 +844,18 @@  static void target_pr_sync_cb(void *arg)
 
 	if (pr_reg_res_holder)
 		__core_scsi3_set_reservation(dev, pr_reg_res_holder,
-					pr_data.pr_scope, pr_data.pr_type);
+					pr_data->pr_scope, pr_data->pr_type);
 	spin_unlock(&dev->dev_reservation_lock);
 
 	if (res_to_delete) {
 		spin_lock(&dev->t10_pr.registration_lock);
 		__core_scsi3_free_registration(dev, pr_prev_res_holder,
-				(pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) ?
+				(pr_data->pro_sa == PRO_PREEMPT_AND_ABORT) ?
 				&preempt_and_abort_list : NULL, 0);
 		spin_unlock(&dev->t10_pr.registration_lock);
 	}
 
-	if (pr_data.pro_sa == PRO_PREEMPT_AND_ABORT) {
+	if (pr_data->pro_sa == PRO_PREEMPT_AND_ABORT) {
 		core_local_lun_reset(dev, NULL, &preempt_and_abort_list, NULL);
 
 		core_scsi3_release_preempt_and_abort(
@@ -845,7 +863,7 @@  static void target_pr_sync_cb(void *arg)
 					pr_reg_res_holder);
 	}
 
-	if (pr_data.pro_sa == PR_SYNC_REASON_RESET) {
+	if (pr_data->pro_sa == PR_SYNC_REASON_RESET) {
 		core_local_lun_reset(dev, NULL, NULL, NULL);
 
 		target_dev_ua_allocate(dev, 0x29,
@@ -856,10 +874,23 @@  static void target_pr_sync_cb(void *arg)
 
 	core_scsi3_update_and_write_aptpl(dev, dev->t10_pr.pr_aptpl_active);
 
-done:
 	kfree(pr_reg_data);
 }
 
+static void target_pr_sync_cb(void *arg)
+{
+	struct pr_reg_lvb *pr_reg_data = NULL;
+	struct se_device *dev = arg;
+	struct pr_lvb pr_data;
+	int res;
+
+	res = target_dlm_read_cluster_data(dev, &pr_data, &pr_reg_data);
+	if (res)
+		return;
+
+	target_dlm_apply_cluster_data(dev, &pr_data, pr_reg_data);
+}
+
 static void
 target_spc2_reserve(struct se_device *dev, struct se_session *sess)
 {