scst: Rework Copy Manager's sysfs interface

The old version had management incompatible with scstadmin and had
issues with LUNs management.



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6694 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2015-11-18 04:09:50 +00:00
parent f2d7532eb1
commit 1c9b1f0baa
8 changed files with 206 additions and 226 deletions
+8 -17
View File
@@ -1859,34 +1859,25 @@ EXTENDED COPY
~~~~~~~~~~~~~
SCST implements EXTENDED COPY via internal Copy Manager target. This
target has the following specific attributes in its sysfs:
target has the following specific attribute in its sysfs:
- allow_not_connected_copy - if not set (default), an initiator can
perform copy only between devices it has direct access to via any
target/session. If set, any initiator can copy between any devices in
the system.
- mgmt - this attribute allows to control data from which devices can
be copied using Copy Manager. By default, devices belonging to dev
handlers with flag auto_cm_assignment_possible set are auto assigned to
the Copy Manager on the registration. Currently, only vdisk has this
flag set, so all other devices (pass-through, user space, etc.) should
be assigned to the Copy Manager manually.
Mgmt attribute supports the following commands:
- add [vname|H:C:I:L] - adds device with name vname or H:C:I:L numbers
(pass-through) to the Copy Manager.
- del [vname|H:C:I:L] - deletes device with name vname or H:C:I:L numbers
(pass-through) from the Copy Manager.
The Copy Manager has access only to those devices, for which it has LUNs
in /sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/.
Devices from scst_vdisk dev handler added to it automatically upon
registration, but for other devices you need to manually add LUNs there
the same way as for any target driver. You can also delete any device at
any time from the Copy Manager visibility by deleting the corresponding
LUN from the sysfs. It might be useful during ALUA state switching.
Internally SCST implements EXTENDED COPY as generation of sets of
internal READ(16) and WRITE(16) SCSI commands. Dev handlers don't need
any manual actions to use it.
Also SCST provides for dev handlers possibility to remap blocks instead
of copy them, if they support this feature. It allows them to perform
EXTENDED COPY command much faster by just metadata update of their
+8 -17
View File
@@ -1712,34 +1712,25 @@ EXTENDED COPY
~~~~~~~~~~~~~
SCST implements EXTENDED COPY via internal Copy Manager target. This
target has the following specific attributes in its sysfs:
target has the following specific attribute in its sysfs:
- allow_not_connected_copy - if not set (default), an initiator can
perform copy only between devices it has direct access to via any
target/session. If set, any initiator can copy between any devices in
the system.
- mgmt - this attribute allows to control data from which devices can
be copied using Copy Manager. By default, devices belonging to dev
handlers with flag auto_cm_assignment_possible set are auto assigned to
the Copy Manager on the registration. Currently, only vdisk has this
flag set, so all other devices (pass-through, user space, etc.) should
be assigned to the Copy Manager manually.
Mgmt attribute supports the following commands:
- add [vname|H:C:I:L] - adds device with name vname or H:C:I:L numbers
(pass-through) to the Copy Manager.
- del [vname|H:C:I:L] - deletes device with name vname or H:C:I:L numbers
(pass-through) from the Copy Manager.
The Copy Manager has access only to those devices, for which it has LUNs
in /sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/.
Devices from scst_vdisk dev handler added to it automatically upon
registration, but for other devices you need to manually add LUNs there
the same way as for any target driver. You can also delete any device at
any time from the Copy Manager visibility by deleting the corresponding
LUN from the sysfs. It might be useful during ALUA state switching.
Internally SCST implements EXTENDED COPY as generation of sets of
internal READ(16) and WRITE(16) SCSI commands. Dev handlers don't need
any manual actions to use it.
Also SCST provides for dev handlers possibility to remap blocks instead
of copy them, if they support this feature. It allows them to perform
EXTENDED COPY command much faster by just metadata update of their
+115 -158
View File
@@ -2519,14 +2519,16 @@ static bool scst_cm_is_lun_free(unsigned int lun)
}
/* scst_mutex supposed to be held and activities suspended */
static int scst_cm_dev_register(struct scst_device *dev)
static int scst_cm_dev_register(struct scst_device *dev, uint64_t lun)
{
int res, i;
unsigned int lun;
struct scst_acg_dev *acg_dev;
bool add_lun;
TRACE_ENTRY();
TRACE_DBG("dev %s, LUN %ld", dev->virt_name, (unsigned long)lun);
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct scst_tgt_dev *tgt_dev;
struct list_head *head = &scst_cm_sess->sess_tgt_dev_list[i];
@@ -2541,18 +2543,25 @@ static int scst_cm_dev_register(struct scst_device *dev)
}
}
while (1) {
lun = scst_cm_next_lun++;
if (lun == SCST_MAX_LUN)
continue;
if (scst_cm_is_lun_free(lun))
break;
};
if (lun == SCST_MAX_LUN) {
add_lun = true;
while (1) {
lun = scst_cm_next_lun++;
if (lun == SCST_MAX_LUN)
continue;
if (scst_cm_is_lun_free(lun))
break;
}
} else
add_lun = false;
res = scst_acg_add_lun(scst_cm_tgt->default_acg,
scst_cm_tgt->tgt_luns_kobj, dev, lun, false, false, &acg_dev);
if (res != 0)
goto out_err;
if (add_lun) {
res = scst_acg_add_lun(scst_cm_tgt->default_acg,
scst_cm_tgt->tgt_luns_kobj, dev, lun, SCST_ADD_LUN_CM,
&acg_dev);
if (res != 0)
goto out_err;
}
spin_lock_bh(&dev->dev_lock);
scst_block_dev(dev);
@@ -2578,13 +2587,15 @@ out_err:
}
/* scst_mutex supposed to be held and activities suspended */
static void scst_cm_dev_unregister(struct scst_device *dev)
static void scst_cm_dev_unregister(struct scst_device *dev, bool del_lun)
{
int i;
struct scst_cm_desig *des, *t;
TRACE_ENTRY();
TRACE_DBG("dev %s, del_lun %d", dev->virt_name, del_lun);
list_for_each_entry_safe(des, t, &scst_cm_desig_list, cm_desig_list_entry) {
if (des->desig_tgt_dev->dev == dev) {
TRACE_DBG("Deleting des %p", des);
@@ -2593,6 +2604,9 @@ static void scst_cm_dev_unregister(struct scst_device *dev)
}
}
if (!del_lun)
goto out;
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct scst_tgt_dev *tgt_dev;
struct list_head *head = &scst_cm_sess->sess_tgt_dev_list[i];
@@ -2606,6 +2620,7 @@ static void scst_cm_dev_unregister(struct scst_device *dev)
}
}
out:
TRACE_EXIT();
return;
}
@@ -2620,7 +2635,7 @@ int scst_cm_on_dev_register(struct scst_device *dev)
if (!dev->handler->auto_cm_assignment_possible)
goto out;
res = scst_cm_dev_register(dev);
res = scst_cm_dev_register(dev, SCST_MAX_LUN);
out:
TRACE_EXIT_RES(res);
@@ -2632,12 +2647,87 @@ void scst_cm_on_dev_unregister(struct scst_device *dev)
{
TRACE_ENTRY();
scst_cm_dev_unregister(dev);
scst_cm_dev_unregister(dev, true);
TRACE_EXIT();
return;
}
/* scst_mutex supposed to be held and activities suspended */
int scst_cm_on_add_acg(struct scst_acg *acg)
{
int res = 0;
TRACE_ENTRY();
if (scst_cm_tgt == NULL)
goto out;
if (acg->tgt != scst_cm_tgt)
goto out;
if (acg != scst_cm_tgt->default_acg) {
PRINT_ERROR("Copy Manager does not support security groups");
res = -EINVAL;
goto out;
}
out:
TRACE_EXIT_RES(res);
return res;
}
/* scst_mutex supposed to be held and activities suspended */
void scst_cm_on_del_acg(struct scst_acg *acg)
{
/* Nothing to do */
}
/* scst_mutex supposed to be held and activities suspended */
int scst_cm_on_add_lun(struct scst_acg_dev *acg_dev, uint64_t lun,
unsigned int *flags)
{
int res = 0;
TRACE_ENTRY();
if (acg_dev->acg != scst_cm_tgt->default_acg)
goto out;
if (acg_dev->acg_dev_rd_only || acg_dev->dev->dev_rd_only) {
PRINT_ERROR("Copy Manager does not support read only devices");
res = -EINVAL;
goto out;
}
*flags &= ~SCST_ADD_LUN_GEN_UA;
res = scst_cm_dev_register(acg_dev->dev, lun);
out:
TRACE_EXIT_RES(res);
return res;
}
/* scst_mutex supposed to be held and activities suspended */
bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev, bool gen_report_luns_changed)
{
bool res = gen_report_luns_changed;
TRACE_ENTRY();
if (acg_dev->acg != scst_cm_tgt->default_acg)
goto out;
scst_cm_dev_unregister(acg_dev->dev, false);
res = false;
out:
TRACE_EXIT_RES(res);
return res;
}
/* scst_mutex supposed to be locked */
static bool scst_cm_check_access_acg(const char *initiator_name,
const struct scst_device *dev, const struct scst_acg *acg,
@@ -3480,148 +3570,8 @@ static struct kobj_attribute scst_cm_allow_not_conn_copy_attr =
scst_cm_allow_not_conn_copy_show,
scst_cm_allow_not_conn_copy_store);
static ssize_t scst_cm_mgmt_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
static const char help[] =
"Usage: echo \"add H:C:I:L\" >mgmt\n"
" echo \"add VNAME\" >mgmt\n"
" echo \"del H:C:I:L\" >mgmt\n"
" echo \"del VNAME\" >mgmt\n";
return sprintf(buf, "%s", help);
}
static int scst_cm_mgmt(struct scst_sysfs_work_item *work)
{
int res = 0;
char *pp, *action, *devstr;
unsigned int host, channel, id, lun;
char *buf = work->buf;
bool vdev;
struct scst_device *d, *dev = NULL;
TRACE_ENTRY();
TRACE_DBG("buffer %s", buf);
pp = buf;
action = scst_get_next_lexem(&pp);
devstr = scst_get_next_lexem(&pp);
if (*devstr == '\0') {
PRINT_ERROR("%s", "Device required");
res = -EINVAL;
goto out;
}
if (*scst_get_next_lexem(&pp) != '\0') {
PRINT_ERROR("%s", "Too many parameters");
res = -EINVAL;
goto out_syntax_err;
}
if (sscanf(devstr, "%u:%u:%u:%u", &host, &channel, &id, &lun) != 4) {
vdev = true;
TRACE_DBG("Virt dev %s", devstr);
} else {
vdev = false;
TRACE_DBG("Pass-through dev %d:%d:%d:%d", host, channel, id, lun);
}
res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER);
if (res != 0)
goto out;
res = mutex_lock_interruptible(&scst_mutex);
if (res != 0)
goto out_resume;
list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
if (vdev) {
if ((d->scsi_dev == NULL) &&
(strcmp(d->virt_name, devstr) == 0)) {
dev = d;
break;
}
} else if (d->scsi_dev != NULL &&
d->scsi_dev->host->host_no == host &&
d->scsi_dev->channel == channel &&
d->scsi_dev->id == id &&
d->scsi_dev->lun == lun) {
dev = d;
break;
}
}
if (dev == NULL) {
PRINT_ERROR("Device %s not found", devstr);
res = -EINVAL;
goto out_unlock;
} else
TRACE_DBG("Dev %p (%s) found", dev, dev->virt_name);
if (strcasecmp("add", action) == 0)
res = scst_cm_dev_register(dev);
else if (strcasecmp("del", action) == 0)
scst_cm_dev_unregister(dev);
else {
PRINT_ERROR("Action %s not understood", action);
res = -EINVAL;
}
out_unlock:
mutex_unlock(&scst_mutex);
out_resume:
scst_resume_activity();
out:
TRACE_EXIT_RES(res);
return res;
out_syntax_err:
PRINT_ERROR("Syntax error on \"%s\"", buf);
res = -EINVAL;
goto out;
}
static ssize_t scst_cm_mgmt_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buffer, size_t size)
{
int res;
struct scst_sysfs_work_item *work;
char *i_buf;
TRACE_ENTRY();
i_buf = kasprintf(GFP_KERNEL, "%.*s", (int)size, buffer);
if (i_buf == NULL) {
PRINT_ERROR("Unable to alloc intermediate buffer with size %zd",
size+1);
res = -ENOMEM;
goto out;
}
res = scst_alloc_sysfs_work(scst_cm_mgmt, false, &work);
if (res != 0)
goto out;
work->buf = i_buf;
res = scst_sysfs_queue_wait_work(work);
if (res == 0)
res = size;
out:
TRACE_EXIT_RES(res);
return res;
}
static struct kobj_attribute scst_cm_mgmt_attr =
__ATTR(mgmt, S_IRUGO|S_IWUSR, scst_cm_mgmt_show, scst_cm_mgmt_store);
static const struct attribute *scst_cm_attrs[] = {
static const struct attribute *scst_cm_tgtt_attrs[] = {
&scst_cm_allow_not_conn_copy_attr.attr,
&scst_cm_mgmt_attr.attr,
NULL,
};
@@ -3693,6 +3643,12 @@ static void scst_cm_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
return;
}
static int scst_cm_report_aen(struct scst_aen *aen)
{
/* Nothing to do */
return 0;
}
static struct scst_tgt_template scst_cm_tgtt = {
.name = SCST_CM_NAME,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
@@ -3710,9 +3666,10 @@ static struct scst_tgt_template scst_cm_tgtt = {
.release = scst_cm_release,
.xmit_response = scst_cm_xmit_response,
.task_mgmt_fn_done = scst_cm_task_mgmt_fn_done,
.report_aen = scst_cm_report_aen,
.get_initiator_port_transport_id = scst_cm_get_initiator_port_transport_id,
#ifndef CONFIG_SCST_PROC
.tgtt_attrs = scst_cm_attrs,
.tgtt_attrs = scst_cm_tgtt_attrs,
#endif
};
+43 -17
View File
@@ -4373,8 +4373,8 @@ out:
/* The activity supposed to be suspended and scst_mutex held */
int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent,
struct scst_device *dev, uint64_t lun, int read_only,
bool gen_scst_report_luns_changed, struct scst_acg_dev **out_acg_dev)
struct scst_device *dev, uint64_t lun, unsigned int flags,
struct scst_acg_dev **out_acg_dev)
{
int res;
struct scst_acg_dev *acg_dev;
@@ -4395,7 +4395,7 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent,
res = -ENOMEM;
goto out;
}
acg_dev->acg_dev_rd_only = read_only;
acg_dev->acg_dev_rd_only = ((flags & SCST_ADD_LUN_READ_ONLY) != 0);
if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) {
/* Devices are allowed to store only CRCs */
acg_dev->acg_dev_dif_guard_format = SCST_DIF_GUARD_FORMAT_CRC;
@@ -4410,6 +4410,12 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent,
list_add_tail(&acg_dev->acg_dev_list_entry, &acg->acg_dev_list);
list_add_tail(&acg_dev->dev_acg_dev_list_entry, &dev->dev_acg_dev_list);
if (!(flags & SCST_ADD_LUN_CM)) {
res = scst_cm_on_add_lun(acg_dev, lun, &flags);
if (res != 0)
goto out_free;
}
list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) {
res = scst_alloc_add_tgt_dev(sess, acg_dev, &tgt_dev);
if (res == -EPERM)
@@ -4423,14 +4429,14 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent,
res = scst_acg_dev_sysfs_create(acg_dev, parent);
if (res != 0)
goto out_free;
goto out_on_del;
if (gen_scst_report_luns_changed)
if (flags & SCST_ADD_LUN_GEN_UA)
scst_report_luns_changed(acg);
PRINT_INFO("Added device %s to group %s (LUN %lld, "
"rd_only %d) to target %s", dev->virt_name, acg->acg_name,
lun, read_only, acg->tgt ? acg->tgt->tgt_name : "?");
"flags 0x%x) to target %s", dev->virt_name, acg->acg_name,
lun, flags, acg->tgt ? acg->tgt->tgt_name : "?");
if (out_acg_dev != NULL)
*out_acg_dev = acg_dev;
@@ -4439,6 +4445,10 @@ out:
TRACE_EXIT_RES(res);
return res;
out_on_del:
if (!(flags & SCST_ADD_LUN_CM))
scst_cm_on_del_lun(acg_dev, false);
out_free:
list_for_each_entry_safe(tgt_dev, tt, &tmp_tgt_dev_list,
extra_tgt_dev_list_entry) {
@@ -4450,7 +4460,7 @@ out_free:
/* The activity supposed to be suspended and scst_mutex held */
int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun,
bool gen_scst_report_luns_changed)
bool gen_report_luns_changed)
{
int res = 0;
struct scst_acg_dev *acg_dev = NULL, *a;
@@ -4470,6 +4480,8 @@ int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun,
goto out;
}
gen_report_luns_changed = scst_cm_on_del_lun(acg_dev, gen_report_luns_changed);
list_for_each_entry_safe(tgt_dev, tt, &acg_dev->dev->dev_tgt_dev_list,
dev_tgt_dev_list_entry) {
if (tgt_dev->acg_dev == acg_dev)
@@ -4478,7 +4490,7 @@ int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun,
scst_del_free_acg_dev(acg_dev, true);
if (gen_scst_report_luns_changed)
if (gen_report_luns_changed)
scst_report_luns_changed(acg);
PRINT_INFO("Removed LUN %lld from group %s (target %s)",
@@ -4490,16 +4502,18 @@ out:
}
/* The activity supposed to be suspended and scst_mutex held */
struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt,
const char *acg_name, bool tgt_acg)
int scst_alloc_add_acg(struct scst_tgt *tgt, const char *acg_name,
bool tgt_acg, struct scst_acg **out_acg)
{
struct scst_acg *acg;
int res;
TRACE_ENTRY();
acg = kzalloc(sizeof(*acg), GFP_KERNEL);
if (acg == NULL) {
PRINT_ERROR("%s", "Allocation of acg failed");
res = -ENOMEM;
goto out;
}
@@ -4512,9 +4526,14 @@ struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt,
acg->acg_name = kstrdup(acg_name, GFP_KERNEL);
if (acg->acg_name == NULL) {
PRINT_ERROR("%s", "Allocation of acg_name failed");
res = -ENOMEM;
goto out_free;
}
res = scst_cm_on_add_acg(acg);
if (res != 0)
goto out_undup;
#ifdef CONFIG_SCST_PROC
acg->addr_method = tgt && tgt->tgtt ? tgt->tgtt->preferred_addr_method
: SCST_LUN_ADDR_METHOD_PERIPHERAL;
@@ -4527,30 +4546,35 @@ struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt,
acg->addr_method = tgt->tgtt->preferred_addr_method;
if (tgt_acg) {
int rc;
TRACE_DBG("Adding acg '%s' to device '%s' acg_list", acg_name,
tgt->tgt_name);
list_add_tail(&acg->acg_list_entry, &tgt->tgt_acg_list);
acg->tgt_acg = 1;
rc = scst_acg_sysfs_create(tgt, acg);
if (rc != 0)
res = scst_acg_sysfs_create(tgt, acg);
if (res != 0)
goto out_del;
}
kobject_get(&tgt->tgt_kobj);
#endif
res = 0;
out:
TRACE_EXIT_HRES(acg);
return acg;
*out_acg = acg;
TRACE_EXIT_RES(res);
return res;
#ifndef CONFIG_SCST_PROC
out_del:
list_del(&acg->acg_list_entry);
#endif
out_undup:
kfree(acg->acg_name);
out_free:
kfree(acg);
acg = NULL;
@@ -4573,6 +4597,8 @@ static void scst_del_acg(struct scst_acg *acg)
scst_assert_activity_suspended();
lockdep_assert_held(&scst_mutex);
scst_cm_on_del_acg(acg);
list_for_each_entry_safe(acg_dev, acg_dev_tmp, &acg->acg_dev_list,
acg_dev_list_entry)
scst_del_acg_dev(acg_dev, true);
+4 -6
View File
@@ -550,8 +550,8 @@ struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt,
if (rc < 0)
goto out_unlock;
tgt->default_acg = scst_alloc_add_acg(tgt, tgt->tgt_name, false);
if (tgt->default_acg == NULL)
rc = scst_alloc_add_acg(tgt, tgt->tgt_name, false, &tgt->default_acg);
if (rc != 0)
goto out_sysfs_del;
#endif
@@ -2650,11 +2650,9 @@ static int __init init_scst(void)
goto out_sysfs_cleanup;
#ifdef CONFIG_SCST_PROC
scst_default_acg = scst_alloc_add_acg(NULL, SCST_DEFAULT_ACG_NAME, false);
if (scst_default_acg == NULL) {
res = -ENOMEM;
res = scst_alloc_add_acg(NULL, SCST_DEFAULT_ACG_NAME, false, &scst_default_acg);
if (res != 0)
goto out_destroy_sgv_pool;
}
#endif
res = scsi_register_interface(&scst_interface);
+15 -5
View File
@@ -347,8 +347,8 @@ int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev);
void scst_free_device(struct scst_device *dev);
bool scst_device_is_exported(struct scst_device *dev);
struct scst_acg *scst_alloc_add_acg(struct scst_tgt *tgt,
const char *acg_name, bool tgt_acg);
int scst_alloc_add_acg(struct scst_tgt *tgt, const char *acg_name,
bool tgt_acg, struct scst_acg **out_acg);
int scst_del_free_acg(struct scst_acg *acg, bool close_sessions);
void scst_get_acg(struct scst_acg *acg);
void scst_put_acg(struct scst_acg *acg);
@@ -363,11 +363,14 @@ void scst_sess_free_tgt_devs(struct scst_session *sess);
struct scst_tgt_dev *scst_lookup_tgt_dev(struct scst_session *sess, u64 lun);
void scst_nexus_loss(struct scst_tgt_dev *tgt_dev, bool queue_UA);
#define SCST_ADD_LUN_READ_ONLY 1
#define SCST_ADD_LUN_GEN_UA 2
#define SCST_ADD_LUN_CM 4
int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent,
struct scst_device *dev, uint64_t lun, int read_only,
bool gen_scst_report_luns_changed, struct scst_acg_dev **out_acg_dev);
struct scst_device *dev, uint64_t lun, unsigned int flags,
struct scst_acg_dev **out_acg_dev);
int scst_acg_del_lun(struct scst_acg *acg, uint64_t lun,
bool gen_scst_report_luns_changed);
bool gen_report_luns_changed);
int scst_acg_add_acn(struct scst_acg *acg, const char *name);
#ifdef CONFIG_SCST_PROC
@@ -857,6 +860,13 @@ static inline bool scst_lba1_inside_lba2(int64_t lba1,
int scst_cm_on_dev_register(struct scst_device *dev);
void scst_cm_on_dev_unregister(struct scst_device *dev);
int scst_cm_on_add_acg(struct scst_acg *acg);
void scst_cm_on_del_acg(struct scst_acg *acg);
int scst_cm_on_add_lun(struct scst_acg_dev *acg_dev, uint64_t lun,
unsigned int *flags);
bool scst_cm_on_del_lun(struct scst_acg_dev *acg_dev,
bool gen_report_luns_changed);
int scst_cm_parse_descriptors(struct scst_cmd *cmd);
void scst_cm_free_descriptors(struct scst_cmd *cmd);
+5 -3
View File
@@ -948,8 +948,8 @@ static int scst_proc_group_add(const char *p, unsigned int addr_method)
}
strlcpy(name, p, len);
acg = scst_alloc_add_acg(NULL, name, false);
if (acg == NULL) {
res = scst_alloc_add_acg(NULL, name, false, &acg);
if (res != 0) {
PRINT_ERROR("scst_alloc_add_acg() (name %s) failed", name);
goto out_free;
}
@@ -969,6 +969,7 @@ out_free_acg:
out_free:
kfree(name);
goto out;
out_nomem:
res = -ENOMEM;
@@ -2069,7 +2070,8 @@ static ssize_t scst_proc_groups_devices_write(struct file *file,
}
}
rc = scst_acg_add_lun(acg, NULL, dev, virt_lun, read_only,
rc = scst_acg_add_lun(acg, NULL, dev, virt_lun,
read_only ? SCST_ADD_LUN_READ_ONLY : 0,
false, NULL);
if (rc) {
res = rc;
+8 -3
View File
@@ -1327,6 +1327,7 @@ static int __scst_process_luns_mgmt_store(char *buffer,
case SCST_LUN_ACTION_REPLACE:
{
bool dev_replaced = false;
unsigned int flags = 0;
e = scst_get_next_lexem(&pp);
res = kstrtoul(e, 0, &virt_lun);
@@ -1414,9 +1415,13 @@ static int __scst_process_luns_mgmt_store(char *buffer,
}
}
if (read_only)
flags |= SCST_ADD_LUN_READ_ONLY;
if (!dev_replaced)
flags |= SCST_ADD_LUN_GEN_UA;
res = scst_acg_add_lun(acg,
tgt_kobj ? tgt->tgt_luns_kobj : acg->luns_kobj,
dev, virt_lun, read_only, !dev_replaced, NULL);
dev, virt_lun, flags, NULL);
if (res != 0)
goto out_unlock;
@@ -2174,8 +2179,8 @@ static int scst_process_ini_group_mgmt_store(char *buffer,
res = -EINVAL;
goto out_unlock;
}
acg = scst_alloc_add_acg(tgt, p, true);
if (acg == NULL)
res = scst_alloc_add_acg(tgt, p, true, &acg);
if (res != 0)
goto out_unlock;
break;
case SCST_INI_GROUP_ACTION_DEL: