@@ -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;
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(-)