mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-18 03:01:26 +00:00
Patch from Alexey Obitotskiy <alexeyo1@open-e.com> with cleanups and fixes implementing setting and managing relative target IDs.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1523 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1180,8 +1180,10 @@ struct scst_tgt {
|
||||
/* Name of the target */
|
||||
char *tgt_name;
|
||||
|
||||
uint16_t rel_tgt_id;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* Name on the default security group ("Default_target_name") */
|
||||
/* Name of the default security group ("Default_target_name") */
|
||||
char *default_group_name;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -355,4 +355,7 @@ enum scst_cdb_flags {
|
||||
|
||||
#define SCST_SYSFS_KEY_MARK "[key]"
|
||||
|
||||
#define SCST_MIN_REL_TGT_ID 1
|
||||
#define SCST_MAX_REL_TGT_ID 65535
|
||||
|
||||
#endif /* __SCST_CONST_H */
|
||||
|
||||
@@ -1881,32 +1881,96 @@ restart:
|
||||
return;
|
||||
}
|
||||
|
||||
struct scst_tgt *scst_alloc_tgt(struct scst_tgt_template *tgtt)
|
||||
bool scst_is_relative_target_port_id_unique(uint16_t id, struct scst_tgt *t)
|
||||
{
|
||||
struct scst_tgt *tgt;
|
||||
bool res = true;
|
||||
struct scst_tgt_template *tgtt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
|
||||
if (tgt == NULL) {
|
||||
mutex_lock(&scst_mutex);
|
||||
list_for_each_entry(tgtt, &scst_template_list,
|
||||
scst_template_list_entry) {
|
||||
struct scst_tgt *tgt;
|
||||
list_for_each_entry(tgt, &tgtt->tgt_list, tgt_list_entry) {
|
||||
if (tgt == t)
|
||||
continue;
|
||||
if (id == tgt->rel_tgt_id) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int gen_relative_target_port_id(uint16_t *id)
|
||||
{
|
||||
int res = -EOVERFLOW;
|
||||
static unsigned long rti = SCST_MIN_REL_TGT_ID, rti_prev;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rti_prev = rti;
|
||||
do {
|
||||
if (scst_is_relative_target_port_id_unique(rti, NULL)) {
|
||||
*id = (uint16_t)rti++;
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
rti++;
|
||||
if (rti > SCST_MAX_REL_TGT_ID)
|
||||
rti = SCST_MIN_REL_TGT_ID;
|
||||
} while (rti != rti_prev);
|
||||
|
||||
PRINT_ERROR("%s", "Unable to create unique relative target port id");
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int scst_alloc_tgt(struct scst_tgt_template *tgtt, struct scst_tgt **tgt)
|
||||
{
|
||||
struct scst_tgt *t;
|
||||
int res = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
t = kzalloc(sizeof(*t), GFP_KERNEL);
|
||||
if (t == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed");
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&tgt->sess_list);
|
||||
init_waitqueue_head(&tgt->unreg_waitQ);
|
||||
tgt->tgtt = tgtt;
|
||||
tgt->sg_tablesize = tgtt->sg_tablesize;
|
||||
spin_lock_init(&tgt->tgt_lock);
|
||||
INIT_LIST_HEAD(&tgt->retry_cmd_list);
|
||||
atomic_set(&tgt->finished_cmds, 0);
|
||||
init_timer(&tgt->retry_timer);
|
||||
tgt->retry_timer.data = (unsigned long)tgt;
|
||||
tgt->retry_timer.function = scst_tgt_retry_timer_fn;
|
||||
INIT_LIST_HEAD(&t->sess_list);
|
||||
init_waitqueue_head(&t->unreg_waitQ);
|
||||
t->tgtt = tgtt;
|
||||
t->sg_tablesize = tgtt->sg_tablesize;
|
||||
spin_lock_init(&t->tgt_lock);
|
||||
INIT_LIST_HEAD(&t->retry_cmd_list);
|
||||
atomic_set(&t->finished_cmds, 0);
|
||||
init_timer(&t->retry_timer);
|
||||
t->retry_timer.data = (unsigned long)t;
|
||||
t->retry_timer.function = scst_tgt_retry_timer_fn;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = gen_relative_target_port_id(&t->rel_tgt_id);
|
||||
if (res != 0) {
|
||||
scst_free_tgt(t);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
*tgt = t;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES((unsigned long)tgt);
|
||||
return tgt;
|
||||
TRACE_EXIT_HRES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void scst_free_tgt(struct scst_tgt *tgt)
|
||||
|
||||
@@ -361,11 +361,9 @@ struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt = scst_alloc_tgt(vtt);
|
||||
if (tgt == NULL) {
|
||||
rc = -ENOMEM;
|
||||
rc = scst_alloc_tgt(vtt, &tgt);
|
||||
if (rc != 0)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
rc = scst_suspend_activity(true);
|
||||
if (rc != 0)
|
||||
@@ -449,8 +447,13 @@ struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
|
||||
mutex_unlock(&scst_mutex);
|
||||
scst_resume_activity();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
PRINT_INFO("Target %s (rel ID %d) for template %s registered successfully",
|
||||
tgt->tgt_name, tgt->rel_tgt_id, vtt->name);
|
||||
#else
|
||||
PRINT_INFO("Target %s for template %s registered successfully",
|
||||
tgt->tgt_name, vtt->name);
|
||||
#endif
|
||||
|
||||
TRACE_DBG("tgt %p", tgt);
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ int scst_queue_retry_cmd(struct scst_cmd *cmd, int finished_cmds);
|
||||
static inline void scst_tgtt_cleanup(struct scst_tgt_template *tgtt) { }
|
||||
static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }
|
||||
|
||||
struct scst_tgt *scst_alloc_tgt(struct scst_tgt_template *tgtt);
|
||||
int scst_alloc_tgt(struct scst_tgt_template *tgtt, struct scst_tgt **tgt);
|
||||
void scst_free_tgt(struct scst_tgt *tgt);
|
||||
|
||||
int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev);
|
||||
@@ -735,6 +735,9 @@ static inline int scst_sn_before(__u32 seq1, __u32 seq2)
|
||||
return (__s32)(seq1-seq2) < 0;
|
||||
}
|
||||
|
||||
bool scst_is_relative_target_port_id_unique(uint16_t id, struct scst_tgt *t);
|
||||
int gen_relative_target_port_id(uint16_t *id);
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
void scst_set_start_time(struct scst_cmd *cmd);
|
||||
|
||||
@@ -112,6 +112,12 @@ static ssize_t scst_ini_group_mgmt_show(struct kobject *kobj,
|
||||
static ssize_t scst_ini_group_mgmt_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t scst_rel_tgt_id_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf);
|
||||
static ssize_t scst_rel_tgt_id_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
static ssize_t scst_acg_luns_mgmt_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf);
|
||||
@@ -526,6 +532,10 @@ static struct kobj_attribute scst_ini_group_mgmt =
|
||||
__ATTR(mgmt, S_IRUGO | S_IWUSR, scst_ini_group_mgmt_show,
|
||||
scst_ini_group_mgmt_store);
|
||||
|
||||
static struct kobj_attribute scst_rel_tgt_id =
|
||||
__ATTR(rel_tgt_id, S_IRUGO | S_IWUSR, scst_rel_tgt_id_show,
|
||||
scst_rel_tgt_id_store);
|
||||
|
||||
static ssize_t scst_tgt_enable_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
@@ -558,6 +568,23 @@ static ssize_t scst_tgt_enable_store(struct kobject *kobj,
|
||||
|
||||
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
|
||||
if (buf[0] == '1') {
|
||||
if (tgt->rel_tgt_id == 0) {
|
||||
res = gen_relative_target_port_id(&tgt->rel_tgt_id);
|
||||
if (res)
|
||||
goto out;
|
||||
PRINT_INFO("Using autogenerated rel ID %d for target "
|
||||
"%s", tgt->rel_tgt_id, tgt->tgt_name);
|
||||
} else
|
||||
if (!scst_is_relative_target_port_id_unique(
|
||||
tgt->rel_tgt_id, tgt)) {
|
||||
PRINT_ERROR("Relative port id %d is not unique",
|
||||
tgt->rel_tgt_id);
|
||||
res = -EBADSLT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
res = tgt->tgtt->enable_target(tgt, buf, count);
|
||||
if (res == 0)
|
||||
res = count;
|
||||
@@ -638,13 +665,21 @@ int scst_create_tgt_sysfs(struct scst_tgt *tgt)
|
||||
}
|
||||
|
||||
retval = sysfs_create_file(tgt->tgt_ini_grp_kobj,
|
||||
&scst_ini_group_mgmt.attr);
|
||||
&scst_ini_group_mgmt.attr);
|
||||
if (retval != 0) {
|
||||
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
|
||||
scst_ini_group_mgmt.attr.name, tgt->tgt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
retval = sysfs_create_file(&tgt->tgt_kobj,
|
||||
&scst_rel_tgt_id.attr);
|
||||
if (retval != 0) {
|
||||
PRINT_ERROR("Can't add attribute %s for tgt %s",
|
||||
scst_rel_tgt_id.attr.name, tgt->tgt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pattr = tgt->tgtt->tgt_attrs;
|
||||
if (pattr != NULL) {
|
||||
while (*pattr != NULL) {
|
||||
@@ -1797,6 +1832,80 @@ out_free_acg:
|
||||
#undef SCST_LUN_ACTION_DEL
|
||||
}
|
||||
|
||||
static ssize_t scst_rel_tgt_id_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct scst_tgt *tgt;
|
||||
int res;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
|
||||
res = sprintf(buf, "%d\n%s", tgt->rel_tgt_id,
|
||||
(tgt->rel_tgt_id != 0) ? SCST_SYSFS_KEY_MARK "\n" : "");
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t scst_rel_tgt_id_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int res = 0;
|
||||
struct scst_tgt *tgt;
|
||||
unsigned long rel_tgt_id;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (buf == NULL)
|
||||
goto out_err;
|
||||
|
||||
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
|
||||
res = strict_strtoul(buf, 0, &rel_tgt_id);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
|
||||
TRACE_DBG("Try to set relative target port id %d",
|
||||
(uint16_t)rel_tgt_id);
|
||||
|
||||
if (rel_tgt_id < SCST_MIN_REL_TGT_ID ||
|
||||
rel_tgt_id > SCST_MAX_REL_TGT_ID) {
|
||||
if ((rel_tgt_id == 0) && !tgt->tgtt->is_target_enabled(tgt))
|
||||
goto set;
|
||||
|
||||
PRINT_ERROR("Invalid relative port id %d",
|
||||
(uint16_t)rel_tgt_id);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tgt->tgtt->is_target_enabled(tgt) &&
|
||||
rel_tgt_id != tgt->rel_tgt_id) {
|
||||
if (!scst_is_relative_target_port_id_unique(rel_tgt_id, tgt)) {
|
||||
PRINT_ERROR("Relative port id %d is not unique",
|
||||
(uint16_t)rel_tgt_id);
|
||||
res = -EBADSLT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
set:
|
||||
tgt->rel_tgt_id = (uint16_t)rel_tgt_id;
|
||||
|
||||
res = count;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_err:
|
||||
PRINT_ERROR("%s: Requested action not understood: %s", __func__, buf);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
int scst_create_acn_sysfs(struct scst_acg *acg, struct scst_acn *acn)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
Reference in New Issue
Block a user