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