diff --git a/fcst/ft_sess.c b/fcst/ft_sess.c index 122e87fb2..78c5f8c5a 100644 --- a/fcst/ft_sess.c +++ b/fcst/ft_sess.c @@ -614,7 +614,7 @@ int ft_tgt_enable(struct scst_tgt *tgt, bool enable) FT_SESS_DBG("enable tgt %s\n", tgt->tgt_name); tport = scst_tgt_get_tgt_priv(tgt); if (tport == NULL) { - ret = -EBUSY; + ret = -E_TGT_PRIV_NOT_YET_SET; goto out_unlock; } tport->enabled = 1; diff --git a/iscsi-scst/kernel/target.c b/iscsi-scst/kernel/target.c index 2cda80f7a..bad7c1444 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 aff1b40af..43177d345 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -6090,23 +6090,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)) || \ @@ -6314,16 +6322,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, @@ -6332,10 +6343,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); @@ -6360,7 +6374,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, @@ -6369,9 +6386,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); @@ -6379,7 +6399,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, @@ -6419,12 +6442,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) { @@ -6456,12 +6481,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); @@ -6508,11 +6535,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 bf9d438c1..bc245c6ff 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -31,6 +31,10 @@ #endif #include +#ifndef __KERNEL__ +#include +#endif + /* * Version numbers, the same as for the kernel. * @@ -519,4 +523,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 d2b9074b1..43160541c 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -408,6 +408,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) @@ -436,6 +438,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) @@ -476,6 +480,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) @@ -502,6 +508,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) @@ -1547,6 +1555,11 @@ static uint16_t scst_local_get_scsi_transport_version(struct scst_tgt *scst_tgt) { struct scst_local_tgt *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 */ else @@ -1557,6 +1570,11 @@ static uint16_t scst_local_get_phys_transport_version(struct scst_tgt *scst_tgt) { struct scst_local_tgt *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 118902894..117d97a2c 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -2333,7 +2333,7 @@ static int srpt_enable_target(struct scst_tgt *scst_tgt, bool enable) EXTRACHECKS_WARN_ON_ONCE(irqs_disabled()); if (!sdev) - return -ENOENT; + return -E_TGT_PRIV_NOT_YET_SET; TRACE_DBG("%s target %s", enable ? "Enabling" : "Disabling", sdev->device->name);