mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 13:11:27 +00:00
scst_sysfs: Rework __scst_process_luns_mgmt_store()
This patch does not change any functionality. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
This commit is contained in:
@@ -1254,11 +1254,96 @@ static void scst_tgt_release(struct kobject *kobj)
|
||||
return;
|
||||
}
|
||||
|
||||
static int scst_parse_add_repl_param(struct scst_acg *acg,
|
||||
struct scst_device *dev, char *pp,
|
||||
unsigned long *virt_lun,
|
||||
bool *read_only)
|
||||
{
|
||||
int res;
|
||||
char *e;
|
||||
|
||||
*read_only = false;
|
||||
e = scst_get_next_lexem(&pp);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
|
||||
res = kstrtoul(e, 0, virt_lun);
|
||||
#else
|
||||
res = strict_strtoul(e, 0, virt_lun);
|
||||
#endif
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Valid LUN required for dev %s (res %d)",
|
||||
dev->virt_name, res);
|
||||
goto out;
|
||||
} else if (*virt_lun > SCST_MAX_LUN) {
|
||||
PRINT_ERROR("Too big LUN %ld (max %d)", *virt_lun, SCST_MAX_LUN);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
unsigned long val;
|
||||
char *param = scst_get_next_token_str(&pp);
|
||||
char *p, *pp;
|
||||
|
||||
if (param == NULL)
|
||||
break;
|
||||
|
||||
p = scst_get_next_lexem(¶m);
|
||||
if (*p == '\0') {
|
||||
PRINT_ERROR("Syntax error at %s (device %s)", param,
|
||||
dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pp = scst_get_next_lexem(¶m);
|
||||
if (*pp == '\0') {
|
||||
PRINT_ERROR("Parameter %s value missed for device %s",
|
||||
p, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (scst_get_next_lexem(¶m)[0] != '\0') {
|
||||
PRINT_ERROR("Too many parameter %s values (device %s)",
|
||||
p, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
|
||||
res = kstrtoul(pp, 0, &val);
|
||||
#else
|
||||
res = strict_strtoul(pp, 0, &val);
|
||||
#endif
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("strict_strtoul() for %s failed: %d "
|
||||
"(device %s)", pp, res, dev->virt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcasecmp("read_only", p) == 0) {
|
||||
*read_only = !!val;
|
||||
TRACE_DBG("READ ONLY %d", *read_only);
|
||||
} else {
|
||||
PRINT_ERROR("Unknown parameter %s (device %s)", p,
|
||||
dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int __scst_process_luns_mgmt_store(char *buffer,
|
||||
struct scst_tgt *tgt, struct scst_acg *acg, bool tgt_kobj)
|
||||
{
|
||||
int res, read_only = 0, action;
|
||||
char *p, *pp, *e;
|
||||
int res, action;
|
||||
bool read_only;
|
||||
char *p, *pp;
|
||||
unsigned long virt_lun;
|
||||
struct scst_acg_dev *acg_dev = NULL, *acg_dev_tmp;
|
||||
struct scst_device *d, *dev = NULL;
|
||||
@@ -1320,77 +1405,10 @@ static int __scst_process_luns_mgmt_store(char *buffer,
|
||||
|
||||
switch (action) {
|
||||
case SCST_LUN_ACTION_ADD:
|
||||
case SCST_LUN_ACTION_REPLACE:
|
||||
{
|
||||
bool dev_replaced = false;
|
||||
|
||||
e = scst_get_next_lexem(&pp);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
|
||||
res = kstrtoul(e, 0, &virt_lun);
|
||||
#else
|
||||
res = strict_strtoul(e, 0, &virt_lun);
|
||||
#endif
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Valid LUN required for dev %s (res %d)", p, res);
|
||||
res = scst_parse_add_repl_param(acg, dev, pp, &virt_lun,
|
||||
&read_only);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
} else if (virt_lun > SCST_MAX_LUN) {
|
||||
PRINT_ERROR("Too big LUN %ld (max %d)", virt_lun, SCST_MAX_LUN);
|
||||
res = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
unsigned long val;
|
||||
char *param = scst_get_next_token_str(&pp);
|
||||
char *pp;
|
||||
|
||||
if (param == NULL)
|
||||
break;
|
||||
|
||||
p = scst_get_next_lexem(¶m);
|
||||
if (*p == '\0') {
|
||||
PRINT_ERROR("Syntax error at %s (device %s)",
|
||||
param, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
pp = scst_get_next_lexem(¶m);
|
||||
if (*pp == '\0') {
|
||||
PRINT_ERROR("Parameter %s value missed for device %s",
|
||||
p, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (scst_get_next_lexem(¶m)[0] != '\0') {
|
||||
PRINT_ERROR("Too many parameter's %s values (device %s)",
|
||||
p, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
|
||||
res = kstrtoul(pp, 0, &val);
|
||||
#else
|
||||
res = strict_strtoul(pp, 0, &val);
|
||||
#endif
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("strict_strtoul() for %s failed: %d "
|
||||
"(device %s)", pp, res, dev->virt_name);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!strcasecmp("read_only", p)) {
|
||||
read_only = val;
|
||||
TRACE_DBG("READ ONLY %d", read_only);
|
||||
} else {
|
||||
PRINT_ERROR("Unknown parameter %s (device %s)",
|
||||
p, dev->virt_name);
|
||||
res = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
acg_dev = NULL;
|
||||
list_for_each_entry(acg_dev_tmp, &acg->acg_dev_list,
|
||||
@@ -1401,23 +1419,46 @@ static int __scst_process_luns_mgmt_store(char *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (acg_dev != NULL) {
|
||||
if (action == SCST_LUN_ACTION_ADD) {
|
||||
PRINT_ERROR("virt lun %ld already exists in "
|
||||
"group %s", virt_lun, acg->acg_name);
|
||||
res = -EEXIST;
|
||||
goto out_unlock;
|
||||
} else {
|
||||
/* Replace */
|
||||
res = scst_acg_del_lun(acg, acg_dev->lun,
|
||||
false);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
if (acg_dev) {
|
||||
PRINT_ERROR("virt lun %ld already exists in "
|
||||
"group %s", virt_lun, acg->acg_name);
|
||||
res = -EEXIST;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
dev_replaced = true;
|
||||
res = scst_acg_add_lun(acg,
|
||||
tgt_kobj ? tgt->tgt_luns_kobj : acg->luns_kobj,
|
||||
dev, virt_lun, read_only, true, NULL);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
|
||||
break;
|
||||
case SCST_LUN_ACTION_REPLACE:
|
||||
{
|
||||
bool dev_replaced = false;
|
||||
|
||||
res = scst_parse_add_repl_param(acg, dev, pp, &virt_lun,
|
||||
&read_only);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
|
||||
acg_dev = NULL;
|
||||
list_for_each_entry(acg_dev_tmp, &acg->acg_dev_list,
|
||||
acg_dev_list_entry) {
|
||||
if (acg_dev_tmp->lun == virt_lun) {
|
||||
acg_dev = acg_dev_tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (acg_dev) {
|
||||
res = scst_acg_del_lun(acg, acg_dev->lun, false);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
|
||||
dev_replaced = true;
|
||||
}
|
||||
|
||||
res = scst_acg_add_lun(acg,
|
||||
tgt_kobj ? tgt->tgt_luns_kobj : acg->luns_kobj,
|
||||
dev, virt_lun, read_only, !dev_replaced, NULL);
|
||||
|
||||
Reference in New Issue
Block a user