diff --git a/fcst/ft_sess.c b/fcst/ft_sess.c index c0e62f1ed..f1ec05c82 100644 --- a/fcst/ft_sess.c +++ b/fcst/ft_sess.c @@ -564,15 +564,22 @@ int ft_tgt_enable(struct scst_tgt *tgt, bool enable) int ret = 0; mutex_lock(&ft_lport_lock); + if (enable) { FT_SESS_DBG("enable tgt %s\n", tgt->tgt_name); tport = scst_tgt_get_tgt_priv(tgt); + if (tport == NULL) { + ret = -E_TGT_PRIV_NOT_YET_SET; + goto out_unlock; + } tport->enabled = 1; tport->lport->service_params |= FCP_SPPF_TARG_FCN; } else { FT_SESS_DBG("disable tgt %s\n", tgt->tgt_name); ft_tgt_release(tgt); } + +out_unlock: mutex_unlock(&ft_lport_lock); return ret; } @@ -581,6 +588,9 @@ bool ft_tgt_enabled(struct scst_tgt *tgt) { struct ft_tport *tport; + if (tgt == NULL) + return false; + tport = scst_tgt_get_tgt_priv(tgt); return tport->enabled; } diff --git a/iscsi-scst/kernel/target.c b/iscsi-scst/kernel/target.c index fdac0b7b6..a7abc6f02 100644 --- a/iscsi-scst/kernel/target.c +++ b/iscsi-scst/kernel/target.c @@ -454,19 +454,22 @@ const struct seq_operations iscsi_seq_op = { static ssize_t iscsi_tgt_tid_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - int pos; + int res = -E_TGT_PRIV_NOT_YET_SET; struct scst_tgt *scst_tgt; struct iscsi_target *tgt; TRACE_ENTRY(); scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct iscsi_target *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; - pos = sprintf(buf, "%u\n", tgt->tid); + res = sprintf(buf, "%u\n", tgt->tid); - TRACE_EXIT_RES(pos); - return pos; +out: + TRACE_EXIT_RES(res); + return res; } static struct kobj_attribute iscsi_tgt_attr_tid = @@ -532,6 +535,11 @@ int iscsi_enable_target(struct scst_tgt *scst_tgt, bool enable) TRACE_ENTRY(); + if (tgt == NULL) { + res = -E_TGT_PRIV_NOT_YET_SET; + goto out; + } + if (enable) type = E_ENABLE_TARGET; else @@ -541,6 +549,7 @@ int iscsi_enable_target(struct scst_tgt *scst_tgt, bool enable) res = iscsi_sysfs_send_event(tgt->tid, type, NULL, NULL, NULL); +out: TRACE_EXIT_RES(res); return res; } @@ -550,7 +559,10 @@ bool iscsi_is_target_enabled(struct scst_tgt *scst_tgt) struct iscsi_target *tgt = (struct iscsi_target *)scst_tgt_get_tgt_priv(scst_tgt); - return tgt->tgt_enabled; + if (tgt != NULL) + return tgt->tgt_enabled; + else + return false; } ssize_t iscsi_sysfs_add_target(const char *target_name, char *params) diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index 33a498635..a239c0f4e 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -5969,23 +5969,31 @@ out: static int q2t_enable_tgt(struct scst_tgt *scst_tgt, bool enable) { struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); - scsi_qla_host_t *ha = tgt->ha; - int res; + scsi_qla_host_t *ha; + int res = -E_TGT_PRIV_NOT_YET_SET; + + if (tgt == NULL) + goto out; + + ha = tgt->ha; if (enable) res = q2t_host_action(ha, ENABLE_TARGET_MODE); else res = q2t_host_action(ha, DISABLE_TARGET_MODE); +out: return res; } static bool q2t_is_tgt_enabled(struct scst_tgt *scst_tgt) { struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); - scsi_qla_host_t *ha = tgt->ha; - return qla_tgt_mode_enabled(ha); + if (tgt == NULL) + return false; + + return qla_tgt_mode_enabled(tgt->ha); } #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) || \ @@ -6193,16 +6201,19 @@ static ssize_t q2t_show_expl_conf_enabled(struct kobject *kobj, struct scst_tgt *scst_tgt; struct q2t_tgt *tgt; scsi_qla_host_t *ha; - ssize_t size; + int res = -E_TGT_PRIV_NOT_YET_SET; scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = tgt->ha; - size = scnprintf(buffer, PAGE_SIZE, "%d\n%s", ha->enable_explicit_conf, + res = scnprintf(buffer, PAGE_SIZE, "%d\n%s", ha->enable_explicit_conf, ha->enable_explicit_conf ? SCST_SYSFS_KEY_MARK "\n" : ""); - return size; +out: + return res; } static ssize_t q2t_store_expl_conf_enabled(struct kobject *kobj, @@ -6211,10 +6222,13 @@ static ssize_t q2t_store_expl_conf_enabled(struct kobject *kobj, struct scst_tgt *scst_tgt; struct q2t_tgt *tgt; scsi_qla_host_t *ha, *pha; + int res = -E_TGT_PRIV_NOT_YET_SET; unsigned long flags; scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = tgt->ha; pha = to_qla_parent(ha); @@ -6239,7 +6253,10 @@ static ssize_t q2t_store_expl_conf_enabled(struct kobject *kobj, spin_unlock_irqrestore(&pha->hardware_lock, flags); - return size; + res = size; + +out: + return res; } static ssize_t q2t_abort_isp_store(struct kobject *kobj, @@ -6248,9 +6265,12 @@ static ssize_t q2t_abort_isp_store(struct kobject *kobj, struct scst_tgt *scst_tgt; struct q2t_tgt *tgt; scsi_qla_host_t *ha; + int res = -E_TGT_PRIV_NOT_YET_SET; scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = tgt->ha; PRINT_INFO("qla2x00t(%ld): Aborting ISP", ha->instance); @@ -6258,7 +6278,10 @@ static ssize_t q2t_abort_isp_store(struct kobject *kobj, set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); qla2x00_wait_for_hba_online(ha); - return size; + res = size; + +out: + return res; } static ssize_t q2t_version_show(struct kobject *kobj, @@ -6298,12 +6321,14 @@ static ssize_t q2t_node_name_show(struct kobject *kobj, struct scst_tgt *scst_tgt; struct q2t_tgt *tgt; scsi_qla_host_t *ha; - ssize_t res; + ssize_t res = -E_TGT_PRIV_NOT_YET_SET; char *wwn; uint8_t *node_name; scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = tgt->ha; if (ha->parent == NULL) { @@ -6335,12 +6360,14 @@ static ssize_t q2t_node_name_store(struct kobject *kobj, struct q2t_tgt *tgt; scsi_qla_host_t *ha; u64 node_name, old_node_name; - int res; + int res = -E_TGT_PRIV_NOT_YET_SET; TRACE_ENTRY(); scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = tgt->ha; sBUG_ON(ha->parent != NULL); @@ -6387,11 +6414,13 @@ static ssize_t q2t_vp_parent_host_show(struct kobject *kobj, struct scst_tgt *scst_tgt; struct q2t_tgt *tgt; scsi_qla_host_t *ha; - ssize_t res; + ssize_t res = -E_TGT_PRIV_NOT_YET_SET; char *wwn; scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + tgt = scst_tgt_get_tgt_priv(scst_tgt); + if (!tgt) + goto out; ha = to_qla_parent(tgt->ha); res = q2t_get_target_name(ha->port_name, &wwn); diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 2b05b723c..f2fdc58ec 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -32,6 +32,10 @@ #endif #include +#ifndef __KERNEL__ +#include +#endif + /* * Version numbers, the same as for the kernel. * @@ -576,4 +580,13 @@ enum scst_tg_sup { #define SCST_MIN_REL_TGT_ID 1 #define SCST_MAX_REL_TGT_ID 65535 +/* + * Error code returned by target attribute sysfs methods if invoked after + * scst_register_target() finished but before before scst_tgt_set_tgt_priv() + * has been invoked. + */ +enum { + E_TGT_PRIV_NOT_YET_SET = EBUSY +}; + #endif /* __SCST_CONST_H */ diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index f52dcd46b..9039424c9 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -394,6 +394,8 @@ static ssize_t scst_local_scsi_transport_version_show(struct kobject *kobj, if (down_read_trylock(&scst_local_exit_rwsem) == 0) goto out; + res = -E_TGT_PRIV_NOT_YET_SET; + scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); tgt = scst_tgt_get_tgt_priv(scst_tgt); if (!tgt) @@ -422,6 +424,8 @@ static ssize_t scst_local_scsi_transport_version_store(struct kobject *kobj, if (down_read_trylock(&scst_local_exit_rwsem) == 0) goto out; + res = -E_TGT_PRIV_NOT_YET_SET; + scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); tgt = scst_tgt_get_tgt_priv(scst_tgt); if (!tgt) @@ -462,6 +466,8 @@ static ssize_t scst_local_phys_transport_version_show(struct kobject *kobj, if (down_read_trylock(&scst_local_exit_rwsem) == 0) goto out; + res = -E_TGT_PRIV_NOT_YET_SET; + scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); tgt = scst_tgt_get_tgt_priv(scst_tgt); if (!tgt) @@ -488,6 +494,8 @@ static ssize_t scst_local_phys_transport_version_store(struct kobject *kobj, if (down_read_trylock(&scst_local_exit_rwsem) == 0) goto out; + res = -E_TGT_PRIV_NOT_YET_SET; + scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj); tgt = scst_tgt_get_tgt_priv(scst_tgt); if (!tgt) @@ -1339,9 +1347,12 @@ static void scst_local_targ_task_mgmt_done(struct scst_mgmt_cmd *mgmt_cmd) static uint16_t scst_local_get_scsi_transport_version(struct scst_tgt *scst_tgt) { - struct scst_local_tgt *tgt; + struct scst_local_tgt *tgt = (struct scst_local_tgt *)scst_tgt_get_tgt_priv(scst_tgt); - tgt = (struct scst_local_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + /* + * It's OK to not check tgt != NULL here, because new sessions + * can't create before its' set. + */ if (tgt->scsi_transport_version == 0) return 0x0BE0; /* SAS */ @@ -1351,9 +1362,12 @@ static uint16_t scst_local_get_scsi_transport_version(struct scst_tgt *scst_tgt) static uint16_t scst_local_get_phys_transport_version(struct scst_tgt *scst_tgt) { - struct scst_local_tgt *tgt; + struct scst_local_tgt *tgt = (struct scst_local_tgt *)scst_tgt_get_tgt_priv(scst_tgt); - tgt = (struct scst_local_tgt *)scst_tgt_get_tgt_priv(scst_tgt); + /* + * It's OK to not check tgt != NULL here, because new sessions + * can't create before its' set. + */ return tgt->phys_transport_version; } diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 0ff66d35f..105c59ad5 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -2365,12 +2365,10 @@ static struct srpt_tgt *srpt_convert_scst_tgt(struct scst_tgt *scst_tgt) if (one_target_per_port) { sport = scst_tgt_get_tgt_priv(scst_tgt); - BUG_ON(!sport); - srpt_tgt = &sport->srpt_tgt; + srpt_tgt = sport ? &sport->srpt_tgt : NULL; } else { sdev = scst_tgt_get_tgt_priv(scst_tgt); - BUG_ON(!sdev); - srpt_tgt = &sdev->srpt_tgt; + srpt_tgt = sdev ? &sdev->srpt_tgt : NULL; } return srpt_tgt; } @@ -2386,7 +2384,7 @@ static int srpt_enable_target(struct scst_tgt *scst_tgt, bool enable) EXTRACHECKS_WARN_ON_ONCE(irqs_disabled()); if (!srpt_tgt) - return -ENOENT; + return -E_TGT_PRIV_NOT_YET_SET; TRACE_DBG("%s target %s", enable ? "Enabling" : "Disabling", scst_tgt->tgt_name); @@ -2407,7 +2405,10 @@ static bool srpt_is_target_enabled(struct scst_tgt *scst_tgt) { struct srpt_tgt *srpt_tgt = srpt_convert_scst_tgt(scst_tgt); - return srpt_tgt && srpt_tgt->enabled; + if (srpt_tgt) + return srpt_tgt->enabled; + else + return false; } #endif @@ -3569,14 +3570,7 @@ static int srpt_release(struct scst_tgt *scst_tgt) EXTRACHECKS_WARN_ON_ONCE(irqs_disabled()); BUG_ON(!scst_tgt); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) - WARN_ON(!srpt_tgt); - if (!srpt_tgt) - return -ENODEV; -#else - if (WARN_ON(!srpt_tgt)) - return -ENODEV; -#endif + BUG_ON(!srpt_tgt); srpt_release_sport(srpt_tgt); @@ -3605,11 +3599,14 @@ static ssize_t show_login_info(struct kobject *kobj, tgt_kobj); struct srpt_tgt *srpt_tgt = srpt_convert_scst_tgt(scst_tgt); struct srpt_port *sport; - int i, len; + int i, res = -E_TGT_PRIV_NOT_YET_SET; + + if (!srpt_tgt) + goto out; if (one_target_per_port) { sport = container_of(srpt_tgt, struct srpt_port, srpt_tgt); - len = sprintf(buf, + res = sprintf(buf, "tid_ext=%016llx,ioc_guid=%016llx,pkey=ffff," "dgid=%04x%04x%04x%04x%04x%04x%04x%04x," "service_id=%016llx\n", @@ -3627,11 +3624,11 @@ static ssize_t show_login_info(struct kobject *kobj, struct srpt_device *sdev; sdev = container_of(srpt_tgt, struct srpt_device, srpt_tgt); - len = 0; + res = 0; for (i = 0; i < sdev->device->phys_port_cnt; i++) { sport = &sdev->port[i]; - len += sprintf(buf + len, + res += sprintf(buf + res, "tid_ext=%016llx,ioc_guid=%016llx,pkey=ffff," "dgid=%04x%04x%04x%04x%04x%04x%04x%04x," "service_id=%016llx\n", @@ -3649,7 +3646,8 @@ static ssize_t show_login_info(struct kobject *kobj, } } - return len; +out: + return res; } static struct kobj_attribute srpt_show_login_info_attr =