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.