Eliminated five more forward declarations.

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3072 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2010-12-15 12:34:43 +00:00
parent 369d76eff4
commit 8ddea02f56

View File

@@ -301,27 +301,12 @@ static ssize_t scst_luns_mgmt_show(struct kobject *kobj,
static ssize_t scst_luns_mgmt_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count);
static ssize_t scst_tgt_cpu_mask_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf);
static ssize_t scst_tgt_cpu_mask_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count);
static ssize_t scst_ini_group_mgmt_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf);
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_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count);
static ssize_t scst_acg_ini_mgmt_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf);
@@ -1382,14 +1367,177 @@ out:
return res;
}
static ssize_t __scst_acg_cpu_mask_show(struct scst_acg *acg, char *buf)
{
int res;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
res = cpumask_scnprintf(buf, SCST_SYSFS_BLOCK_SIZE,
acg->acg_cpu_mask);
#else
res = cpumask_scnprintf(buf, SCST_SYSFS_BLOCK_SIZE,
&acg->acg_cpu_mask);
#endif
if (!cpus_equal(acg->acg_cpu_mask, default_cpu_mask))
res += sprintf(&buf[res], "\n%s\n", SCST_SYSFS_KEY_MARK);
return res;
}
static int __scst_acg_process_cpu_mask_store(struct scst_tgt *tgt,
struct scst_acg *acg, cpumask_t *cpu_mask)
{
int res = 0;
struct scst_session *sess;
TRACE_DBG("tgt %p, acg %p", tgt, acg);
if (mutex_lock_interruptible(&scst_mutex) != 0) {
res = -EINTR;
goto out;
}
/* Check if tgt and acg not already freed while we were coming here */
if (scst_check_tgt_acg_ptrs(tgt, acg) != 0)
goto out_unlock;
cpumask_copy(&acg->acg_cpu_mask, cpu_mask);
list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) {
int i;
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct scst_tgt_dev *tgt_dev;
struct list_head *head = &sess->sess_tgt_dev_list[i];
list_for_each_entry(tgt_dev, head,
sess_tgt_dev_list_entry) {
struct scst_cmd_thread_t *thr;
if (tgt_dev->active_cmd_threads != &tgt_dev->tgt_dev_cmd_threads)
continue;
list_for_each_entry(thr,
&tgt_dev->active_cmd_threads->threads_list,
thread_list_entry) {
int rc;
rc = set_cpus_allowed_ptr(thr->cmd_thread, cpu_mask);
if (rc != 0)
PRINT_ERROR("Setting CPU "
"affinity failed: %d", rc);
}
}
}
if (tgt->tgtt->report_aen != NULL) {
struct scst_aen *aen;
int rc;
aen = scst_alloc_aen(sess, 0);
if (aen == NULL) {
PRINT_ERROR("Unable to notify target driver %s "
"about cpu_mask change", tgt->tgt_name);
continue;
}
aen->event_fn = SCST_AEN_CPU_MASK_CHANGED;
TRACE_DBG("Calling target's %s report_aen(%p)",
tgt->tgtt->name, aen);
rc = tgt->tgtt->report_aen(aen);
TRACE_DBG("Target's %s report_aen(%p) returned %d",
tgt->tgtt->name, aen, rc);
if (rc != SCST_AEN_RES_SUCCESS)
scst_free_aen(aen);
}
}
out_unlock:
mutex_unlock(&scst_mutex);
out:
return res;
}
static int __scst_acg_cpu_mask_store_work_fn(struct scst_sysfs_work_item *work)
{
return __scst_acg_process_cpu_mask_store(work->tgt, work->acg,
&work->cpu_mask);
}
static ssize_t __scst_acg_cpu_mask_store(struct scst_acg *acg,
const char *buf, size_t count)
{
int res;
struct scst_sysfs_work_item *work;
/* cpumask might be too big for stack */
res = scst_alloc_sysfs_work(__scst_acg_cpu_mask_store_work_fn,
false, &work);
if (res != 0)
goto out;
/*
* We can't use cpumask_parse_user() here, because it expects
* buffer in the user space.
*/
res = __bitmap_parse(buf, count, 0, cpumask_bits(&work->cpu_mask),
nr_cpumask_bits);
if (res != 0) {
PRINT_ERROR("__bitmap_parse() failed: %d", res);
goto out_release;
}
if (cpus_equal(acg->acg_cpu_mask, work->cpu_mask))
goto out;
work->tgt = acg->tgt;
work->acg = acg;
res = scst_sysfs_queue_wait_work(work);
out:
return res;
out_release:
scst_sysfs_work_release(&work->sysfs_work_kref);
goto out;
}
static ssize_t scst_tgt_cpu_mask_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_acg *acg;
struct scst_tgt *tgt;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
acg = tgt->default_acg;
return __scst_acg_cpu_mask_show(acg, buf);
}
static ssize_t scst_tgt_cpu_mask_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int res;
struct scst_acg *acg;
struct scst_tgt *tgt;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
acg = tgt->default_acg;
res = __scst_acg_cpu_mask_store(acg, buf, count);
if (res != 0)
goto out;
res = count;
out:
TRACE_EXIT_RES(res);
return res;
}
static struct kobj_attribute scst_luns_mgmt =
__ATTR(mgmt, S_IRUGO | S_IWUSR, scst_luns_mgmt_show,
scst_luns_mgmt_store);
static struct kobj_attribute scst_acg_luns_mgmt =
__ATTR(mgmt, S_IRUGO | S_IWUSR, scst_luns_mgmt_show,
scst_acg_luns_mgmt_store);
static struct kobj_attribute scst_acg_ini_mgmt =
__ATTR(mgmt, S_IRUGO | S_IWUSR, scst_acg_ini_mgmt_show,
scst_acg_ini_mgmt_store);
@@ -1412,10 +1560,6 @@ static struct kobj_attribute scst_tgt_cpu_mask =
scst_tgt_cpu_mask_show,
scst_tgt_cpu_mask_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 struct kobj_attribute scst_acg_addr_method =
__ATTR(addr_method, S_IRUGO | S_IWUSR, scst_acg_addr_method_show,
scst_acg_addr_method_store);
@@ -1546,6 +1690,112 @@ static struct kobj_attribute tgt_enable_attr =
__ATTR(enabled, S_IRUGO | S_IWUSR,
scst_tgt_enable_show, scst_tgt_enable_store);
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 int scst_process_rel_tgt_id_store(struct scst_sysfs_work_item *work)
{
int res = 0;
struct scst_tgt *tgt = work->tgt;
unsigned long rel_tgt_id = work->l;
TRACE_ENTRY();
/* tgt protected by kobject_get() */
TRACE_DBG("Trying to set relative target port id %d",
(uint16_t)rel_tgt_id);
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_put;
}
}
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_put;
}
set:
tgt->rel_tgt_id = (uint16_t)rel_tgt_id;
out_put:
kobject_put(&tgt->tgt_kobj);
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;
struct scst_sysfs_work_item *work;
TRACE_ENTRY();
if (buf == NULL)
goto out;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
res = strict_strtoul(buf, 0, &rel_tgt_id);
if (res != 0) {
PRINT_ERROR("%s", "Wrong rel_tgt_id");
res = -EINVAL;
goto out;
}
res = scst_alloc_sysfs_work(scst_process_rel_tgt_id_store, false,
&work);
if (res != 0)
goto out;
work->tgt = tgt;
work->l = rel_tgt_id;
kobject_get(&tgt->tgt_kobj);
res = scst_sysfs_queue_wait_work(work);
if (res == 0)
res = count;
out:
TRACE_EXIT_RES(res);
return res;
}
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);
/*
* Supposed to be called under scst_mutex. In case of error will drop,
* then reacquire it.
@@ -3044,6 +3294,10 @@ out_del:
goto out;
}
/**
** ini_groups directory implementation.
**/
static int __scst_process_luns_mgmt_store(char *buffer,
struct scst_tgt *tgt, struct scst_acg *acg, bool tgt_kobj)
{
@@ -3368,286 +3622,23 @@ static ssize_t scst_luns_mgmt_store(struct kobject *kobj,
return res;
}
static ssize_t __scst_acg_cpu_mask_show(struct scst_acg *acg, char *buf)
{
int res;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
res = cpumask_scnprintf(buf, SCST_SYSFS_BLOCK_SIZE,
acg->acg_cpu_mask);
#else
res = cpumask_scnprintf(buf, SCST_SYSFS_BLOCK_SIZE,
&acg->acg_cpu_mask);
#endif
if (!cpus_equal(acg->acg_cpu_mask, default_cpu_mask))
res += sprintf(&buf[res], "\n%s\n", SCST_SYSFS_KEY_MARK);
return res;
}
static int __scst_acg_process_cpu_mask_store(struct scst_tgt *tgt,
struct scst_acg *acg, cpumask_t *cpu_mask)
{
int res = 0;
struct scst_session *sess;
TRACE_DBG("tgt %p, acg %p", tgt, acg);
if (mutex_lock_interruptible(&scst_mutex) != 0) {
res = -EINTR;
goto out;
}
/* Check if tgt and acg not already freed while we were coming here */
if (scst_check_tgt_acg_ptrs(tgt, acg) != 0)
goto out_unlock;
cpumask_copy(&acg->acg_cpu_mask, cpu_mask);
list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) {
int i;
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct scst_tgt_dev *tgt_dev;
struct list_head *head = &sess->sess_tgt_dev_list[i];
list_for_each_entry(tgt_dev, head,
sess_tgt_dev_list_entry) {
struct scst_cmd_thread_t *thr;
if (tgt_dev->active_cmd_threads != &tgt_dev->tgt_dev_cmd_threads)
continue;
list_for_each_entry(thr,
&tgt_dev->active_cmd_threads->threads_list,
thread_list_entry) {
int rc;
rc = set_cpus_allowed_ptr(thr->cmd_thread, cpu_mask);
if (rc != 0)
PRINT_ERROR("Setting CPU "
"affinity failed: %d", rc);
}
}
}
if (tgt->tgtt->report_aen != NULL) {
struct scst_aen *aen;
int rc;
aen = scst_alloc_aen(sess, 0);
if (aen == NULL) {
PRINT_ERROR("Unable to notify target driver %s "
"about cpu_mask change", tgt->tgt_name);
continue;
}
aen->event_fn = SCST_AEN_CPU_MASK_CHANGED;
TRACE_DBG("Calling target's %s report_aen(%p)",
tgt->tgtt->name, aen);
rc = tgt->tgtt->report_aen(aen);
TRACE_DBG("Target's %s report_aen(%p) returned %d",
tgt->tgtt->name, aen, rc);
if (rc != SCST_AEN_RES_SUCCESS)
scst_free_aen(aen);
}
}
out_unlock:
mutex_unlock(&scst_mutex);
out:
return res;
}
static int __scst_acg_cpu_mask_store_work_fn(struct scst_sysfs_work_item *work)
{
return __scst_acg_process_cpu_mask_store(work->tgt, work->acg,
&work->cpu_mask);
}
static ssize_t __scst_acg_cpu_mask_store(struct scst_acg *acg,
const char *buf, size_t count)
{
int res;
struct scst_sysfs_work_item *work;
/* cpumask might be too big for stack */
res = scst_alloc_sysfs_work(__scst_acg_cpu_mask_store_work_fn,
false, &work);
if (res != 0)
goto out;
/*
* We can't use cpumask_parse_user() here, because it expects
* buffer in the user space.
*/
res = __bitmap_parse(buf, count, 0, cpumask_bits(&work->cpu_mask),
nr_cpumask_bits);
if (res != 0) {
PRINT_ERROR("__bitmap_parse() failed: %d", res);
goto out_release;
}
if (cpus_equal(acg->acg_cpu_mask, work->cpu_mask))
goto out;
work->tgt = acg->tgt;
work->acg = acg;
res = scst_sysfs_queue_wait_work(work);
out:
return res;
out_release:
scst_sysfs_work_release(&work->sysfs_work_kref);
goto out;
}
static ssize_t scst_tgt_cpu_mask_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_acg *acg;
struct scst_tgt *tgt;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
acg = tgt->default_acg;
return __scst_acg_cpu_mask_show(acg, buf);
}
static ssize_t scst_tgt_cpu_mask_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
static ssize_t scst_acg_luns_mgmt_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int res;
struct scst_acg *acg;
struct scst_tgt *tgt;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
acg = tgt->default_acg;
acg = container_of(kobj->parent, struct scst_acg, acg_kobj);
res = __scst_luns_mgmt_store(acg, false, buf, count);
res = __scst_acg_cpu_mask_store(acg, buf, count);
if (res != 0)
goto out;
res = count;
out:
TRACE_EXIT_RES(res);
return res;
}
/*
* Called with scst_mutex held.
*
* !! No sysfs works must use kobject_get() to protect acg, due to possible
* !! deadlock with scst_mutex (it is waiting for the last put, but
* !! the last ref counter holder is waiting for scst_mutex)
*/
void scst_acg_sysfs_del(struct scst_acg *acg)
{
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
acg->acg_kobj_release_cmpl = &c;
kobject_del(acg->luns_kobj);
kobject_del(acg->initiators_kobj);
kobject_del(&acg->acg_kobj);
kobject_put(acg->luns_kobj);
kobject_put(acg->initiators_kobj);
kobject_put(&acg->acg_kobj);
rc = wait_for_completion_timeout(acg->acg_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for acg %s (%d refs)...", acg->acg_name,
atomic_read(&acg->acg_kobj.kref.refcount));
wait_for_completion(acg->acg_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for acg %s", acg->acg_name);
}
TRACE_EXIT();
return;
}
int scst_acg_sysfs_create(struct scst_tgt *tgt,
struct scst_acg *acg)
{
int res = 0;
TRACE_ENTRY();
res = kobject_init_and_add(&acg->acg_kobj, &acg_ktype,
tgt->tgt_ini_grp_kobj, acg->acg_name);
if (res != 0) {
PRINT_ERROR("Can't add acg '%s' to sysfs", acg->acg_name);
goto out;
}
acg->luns_kobj = kobject_create_and_add("luns", &acg->acg_kobj);
if (acg->luns_kobj == NULL) {
PRINT_ERROR("Can't create luns kobj for tgt %s",
tgt->tgt_name);
res = -ENOMEM;
goto out_del;
}
res = sysfs_create_file(acg->luns_kobj, &scst_acg_luns_mgmt.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_luns_mgmt.attr.name, tgt->tgt_name);
goto out_del;
}
acg->initiators_kobj = kobject_create_and_add("initiators",
&acg->acg_kobj);
if (acg->initiators_kobj == NULL) {
PRINT_ERROR("Can't create initiators kobj for tgt %s",
tgt->tgt_name);
res = -ENOMEM;
goto out_del;
}
res = sysfs_create_file(acg->initiators_kobj,
&scst_acg_ini_mgmt.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_ini_mgmt.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_addr_method.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_addr_method.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_io_grouping_type.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_io_grouping_type.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_cpu_mask.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_cpu_mask.attr.name, tgt->tgt_name);
goto out_del;
}
out:
TRACE_EXIT_RES(res);
return res;
out_del:
scst_acg_sysfs_del(acg);
goto out;
}
static struct kobj_attribute scst_acg_luns_mgmt =
__ATTR(mgmt, S_IRUGO | S_IWUSR, scst_luns_mgmt_show,
scst_acg_luns_mgmt_store);
static ssize_t scst_acg_addr_method_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -3891,108 +3882,124 @@ out_free:
goto out;
}
static ssize_t scst_rel_tgt_id_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
/*
* Called with scst_mutex held.
*
* !! No sysfs works must use kobject_get() to protect acg, due to possible
* !! deadlock with scst_mutex (it is waiting for the last put, but
* !! the last ref counter holder is waiting for scst_mutex)
*/
void scst_acg_sysfs_del(struct scst_acg *acg)
{
struct scst_tgt *tgt;
int res;
int rc;
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
acg->acg_kobj_release_cmpl = &c;
res = sprintf(buf, "%d\n%s", tgt->rel_tgt_id,
(tgt->rel_tgt_id != 0) ? SCST_SYSFS_KEY_MARK "\n" : "");
kobject_del(acg->luns_kobj);
kobject_del(acg->initiators_kobj);
kobject_del(&acg->acg_kobj);
TRACE_EXIT_RES(res);
return res;
}
kobject_put(acg->luns_kobj);
kobject_put(acg->initiators_kobj);
kobject_put(&acg->acg_kobj);
static int scst_process_rel_tgt_id_store(struct scst_sysfs_work_item *work)
{
int res = 0;
struct scst_tgt *tgt = work->tgt;
unsigned long rel_tgt_id = work->l;
TRACE_ENTRY();
/* tgt protected by kobject_get() */
TRACE_DBG("Trying to set relative target port id %d",
(uint16_t)rel_tgt_id);
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_put;
}
rc = wait_for_completion_timeout(acg->acg_kobj_release_cmpl, HZ);
if (rc == 0) {
PRINT_INFO("Waiting for releasing sysfs entry "
"for acg %s (%d refs)...", acg->acg_name,
atomic_read(&acg->acg_kobj.kref.refcount));
wait_for_completion(acg->acg_kobj_release_cmpl);
PRINT_INFO("Done waiting for releasing sysfs "
"entry for acg %s", acg->acg_name);
}
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_put;
}
set:
tgt->rel_tgt_id = (uint16_t)rel_tgt_id;
out_put:
kobject_put(&tgt->tgt_kobj);
TRACE_EXIT_RES(res);
return res;
TRACE_EXIT();
return;
}
static ssize_t scst_rel_tgt_id_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
int scst_acg_sysfs_create(struct scst_tgt *tgt,
struct scst_acg *acg)
{
int res = 0;
struct scst_tgt *tgt;
unsigned long rel_tgt_id;
struct scst_sysfs_work_item *work;
TRACE_ENTRY();
if (buf == NULL)
goto out;
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
res = strict_strtoul(buf, 0, &rel_tgt_id);
res = kobject_init_and_add(&acg->acg_kobj, &acg_ktype,
tgt->tgt_ini_grp_kobj, acg->acg_name);
if (res != 0) {
PRINT_ERROR("%s", "Wrong rel_tgt_id");
res = -EINVAL;
PRINT_ERROR("Can't add acg '%s' to sysfs", acg->acg_name);
goto out;
}
res = scst_alloc_sysfs_work(scst_process_rel_tgt_id_store, false,
&work);
if (res != 0)
goto out;
acg->luns_kobj = kobject_create_and_add("luns", &acg->acg_kobj);
if (acg->luns_kobj == NULL) {
PRINT_ERROR("Can't create luns kobj for tgt %s",
tgt->tgt_name);
res = -ENOMEM;
goto out_del;
}
work->tgt = tgt;
work->l = rel_tgt_id;
res = sysfs_create_file(acg->luns_kobj, &scst_acg_luns_mgmt.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_luns_mgmt.attr.name, tgt->tgt_name);
goto out_del;
}
kobject_get(&tgt->tgt_kobj);
acg->initiators_kobj = kobject_create_and_add("initiators",
&acg->acg_kobj);
if (acg->initiators_kobj == NULL) {
PRINT_ERROR("Can't create initiators kobj for tgt %s",
tgt->tgt_name);
res = -ENOMEM;
goto out_del;
}
res = scst_sysfs_queue_wait_work(work);
if (res == 0)
res = count;
res = sysfs_create_file(acg->initiators_kobj,
&scst_acg_ini_mgmt.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_ini_mgmt.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_addr_method.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_addr_method.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_io_grouping_type.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_io_grouping_type.attr.name, tgt->tgt_name);
goto out_del;
}
res = sysfs_create_file(&acg->acg_kobj, &scst_acg_cpu_mask.attr);
if (res != 0) {
PRINT_ERROR("Can't add tgt attr %s for tgt %s",
scst_acg_cpu_mask.attr.name, tgt->tgt_name);
goto out_del;
}
out:
TRACE_EXIT_RES(res);
return res;
out_del:
scst_acg_sysfs_del(acg);
goto out;
}
/**
** acn
**/
int scst_acn_sysfs_create(struct scst_acn *acn)
{
int res = 0;
@@ -4080,19 +4087,9 @@ static ssize_t scst_acn_file_show(struct kobject *kobj,
attr->attr.name);
}
static ssize_t scst_acg_luns_mgmt_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int res;
struct scst_acg *acg;
acg = container_of(kobj->parent, struct scst_acg, acg_kobj);
res = __scst_luns_mgmt_store(acg, false, buf, count);
TRACE_EXIT_RES(res);
return res;
}
/**
** acg_ini_mgmt
**/
static ssize_t scst_acg_ini_mgmt_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)