mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 13:11:27 +00:00
Avoid that enabling a target too quickly triggers a crash (merge r4515 from trunk)
git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@6079 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#endif
|
||||
#include <scsi/scsi.h>
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#include <errno.h>
|
||||
#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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user