diff mbox series

[RFC,48/48] target: cluster: request data on initial sync

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

Commit Message

Dmitry Bogdanov March 25, 2022, 7:58 a.m. UTC
If there is no cluster data in cluster (master node died), request it
from alive nodes.

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

Patch

diff --git a/drivers/target/target_cluster_dlm.c b/drivers/target/target_cluster_dlm.c
index ff0c207be141..39754d3671b7 100644
--- a/drivers/target/target_cluster_dlm.c
+++ b/drivers/target/target_cluster_dlm.c
@@ -19,6 +19,7 @@  struct target_cluster_data {
 	struct dlm_ckv_lock *pr_lock;
 	struct dlm_ckv_kv *pr_data;
 	struct dlm_ckv_notify *pr_sync_notify;
+	struct dlm_ckv_notify *init_sync_notify;
 	int reserved_node_id;
 	struct dlm_ckv_kv **pr_reg_kv;
 	size_t pr_reg_kv_len;
@@ -101,7 +102,10 @@  struct async_group {
 
 #define PR_SYNC_REASON_RESERVE	10
 #define PR_SYNC_REASON_RESET	11
+#define PR_SYNC_REASON_INIT	13
 
+static void target_initial_sync(struct se_device *dev);
+static void target_initial_sync_cb(void *arg);
 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,
@@ -157,15 +161,22 @@  static int target_init_dlm(struct se_device *dev)
 	if (!cluster_data->pr_sync_notify)
 		goto fail;
 
+	cluster_data->init_sync_notify = dlm_ckv_create_notification(
+		cluster_data->bucket, "init_sync", target_initial_sync_cb);
+	if (!cluster_data->init_sync_notify)
+		goto fail;
+
 	dev->cluster_data = cluster_data;
 
 	/* initial sync-up on joining the cluster */
 	dlm_ckv_lock_get(cluster_data->pr_lock);
-	target_pr_sync_cb(dev);
+	target_initial_sync(dev);
 	dlm_ckv_lock_release(cluster_data->pr_lock);
 
 	return err;
 fail:
+	if (cluster_data->init_sync_notify)
+		dlm_ckv_free_notification(cluster_data->init_sync_notify);
 	if (cluster_data->pr_sync_notify)
 		dlm_ckv_free_notification(cluster_data->pr_sync_notify);
 	if (cluster_data->pr_lock)
@@ -188,6 +199,7 @@  static int target_cleanup_dlm(struct se_device *dev)
 			dlm_ckv_free_kv(cluster_data->pr_reg_kv[i]);
 	kfree(cluster_data->pr_reg_kv);
 
+	dlm_ckv_free_notification(cluster_data->init_sync_notify);
 	dlm_ckv_free_notification(cluster_data->pr_sync_notify);
 	dlm_ckv_free_lock(cluster_data->pr_lock);
 	dlm_ckv_free_kv(cluster_data->pr_data);
@@ -410,6 +422,13 @@  static int target_pr_sync_dlm(struct se_device *dev, u8 pro_sa)
 	return res;
 }
 
+static void target_initial_sync_cb(void *arg)
+{
+	struct se_device *dev = arg;
+
+	target_pr_sync_dlm(dev, PR_SYNC_REASON_INIT);
+}
+
 static int target_update_pr_reg(struct se_device *dev,
 				struct t10_pr_registration *pr_reg,
 				const struct pr_lvb *pr_data,
@@ -584,6 +603,7 @@  static int target_dlm_read_cluster_data(
 	if (!pr_data->version) {
 		pr_info("TARGET_CORE[%d]: PR data from cluster is invalid\n",
 			dev->dev_index);
+		res = -ENOLCK;
 		goto done;
 	}
 
@@ -877,6 +897,20 @@  static void target_dlm_apply_cluster_data(
 	kfree(pr_reg_data);
 }
 
+static void target_initial_sync(struct se_device *dev)
+{
+	struct target_cluster_data *cluster_data = dev->cluster_data;
+	struct pr_reg_lvb *pr_reg_data = NULL;
+	struct pr_lvb pr_data;
+	int res;
+
+	res = target_dlm_read_cluster_data(dev, &pr_data, &pr_reg_data);
+	if (!res)
+		target_dlm_apply_cluster_data(dev, &pr_data, pr_reg_data);
+	if (res == -ENOLCK)
+		dlm_ckv_notify(cluster_data->init_sync_notify);
+}
+
 static void target_pr_sync_cb(void *arg)
 {
 	struct pr_reg_lvb *pr_reg_data = NULL;