From 9608cd5781c43fca772515d876f1c5a20acaba85 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 21 Feb 2019 16:07:52 +0000 Subject: [PATCH] scst_pres: Make PERSISTENT RESERVE OUT ALL_TG_PT flag support remote ports Instead of only iterating over local ports, also iterate over remote ports. Signed-off-by: Sergey Lysanov [bvanassche: edited patch title and description, introduced a helper function, register remote ports once, added error checking] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7969 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_pres.c | 42 +++++++++++++++++++++++++++++++++++++++++- scst/src/scst_priv.h | 1 + scst/src/scst_tg.c | 5 +++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 1f69d1380..e1bf203cf 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -1549,7 +1549,44 @@ out: return res; } -/* Called with dev_pr_mutex locked, no IRQ */ +/* Add registrants for remote ports. Called with dev_pr_mutex locked, no IRQ. */ +static int scst_register_remote_ports(struct scst_cmd *cmd, uint8_t *buffer, + int buffer_size, bool spec_i_pt, struct list_head *rollback_list) +{ + struct scst_dev_group *dg; + struct scst_target_group *tg; + struct scst_tg_tgt *tgtgt; + int res = 0; + + scst_alua_lock(); + + dg = scst_lookup_dg_by_dev(cmd->dev); + if (!dg) + goto out_unlock; + + list_for_each_entry(tg, &dg->tg_list, entry) { + list_for_each_entry(tgtgt, &tg->tgt_list, entry) { + /* Skip local target ports */ + if (tgtgt->tgt) + continue; + /* To do: check the initiator port transport ID. */ + if (tgtgt->rel_tgt_id == 0) + continue; + res = scst_pr_register_on_tgt_id(cmd, tgtgt->rel_tgt_id, + buffer, buffer_size, + spec_i_pt, + rollback_list); + if (res != 0) + goto out_unlock; + } + } +out_unlock: + scst_alua_unlock(); + + return res; +} + +/* Register all target ports. Called with dev_pr_mutex locked, no IRQ. */ static int scst_pr_register_all_tg_pt(struct scst_cmd *cmd, uint8_t *buffer, int buffer_size, bool spec_i_pt, struct list_head *rollback_list) { @@ -1594,6 +1631,9 @@ static int scst_pr_register_all_tg_pt(struct scst_cmd *cmd, uint8_t *buffer, } } + res = scst_register_remote_ports(cmd, buffer, buffer_size, spec_i_pt, + rollback_list); + out_unlock: mutex_unlock(&scst_mutex2); diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index a5bab7e9e..9e933314d 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -488,6 +488,7 @@ void scst_tg_cleanup(void); int scst_dg_add(struct kobject *parent, const char *name); int scst_dg_remove(const char *name); struct scst_dev_group *scst_lookup_dg_by_kobj(struct kobject *kobj); +struct scst_dev_group *scst_lookup_dg_by_dev(struct scst_device *dev); int scst_dg_dev_add(struct scst_dev_group *dg, const char *name); int scst_dg_dev_remove_by_name(struct scst_dev_group *dg, const char *name); int scst_dg_dev_remove_by_dev(struct scst_device *dev); diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index bdd8437ba..719e4d336 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -1403,6 +1403,11 @@ out: return dg; } +struct scst_dev_group *scst_lookup_dg_by_dev(struct scst_device *dev) +{ + return __lookup_dg_by_dev(dev); +} + /* * Target group module management.