diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 4423bd96b..396e168c0 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -707,11 +707,30 @@ out: return res; } +/* scst_vdisk_mutex supposed to be held */ +static struct scst_vdisk_dev *vdev_find(const char *name) +{ + struct scst_vdisk_dev *res, *vv; + + TRACE_ENTRY(); + + res = NULL; + list_for_each_entry(vv, &vdev_list, vdev_list_entry) { + if (strcmp(vv->name, name) == 0) { + res = vv; + break; + } + } + + TRACE_EXIT_HRES((unsigned long)res); + return res; +} + static int vdisk_attach(struct scst_device *dev) { int res = 0; loff_t err; - struct scst_vdisk_dev *virt_dev = NULL, *vv; + struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -727,13 +746,7 @@ static int vdisk_attach(struct scst_device *dev) * scst_vdisk_mutex must be already taken before * scst_register_virtual_device() */ - list_for_each_entry(vv, &vdev_list, vdev_list_entry) { - if (strcmp(vv->name, dev->virt_name) == 0) { - virt_dev = vv; - break; - } - } - + virt_dev = vdev_find(dev->virt_name); if (virt_dev == NULL) { PRINT_ERROR("Device %s not found", dev->virt_name); res = -EINVAL; @@ -3366,10 +3379,14 @@ out: static int vdev_create(struct scst_dev_type *devt, const char *name, struct scst_vdisk_dev **res_virt_dev) { - int res = 0; + int res; struct scst_vdisk_dev *virt_dev; uint64_t dev_id_num; + res = -EEXIST; + if (vdev_find(name)) + goto out; + virt_dev = kzalloc(sizeof(*virt_dev), GFP_KERNEL); if (virt_dev == NULL) { PRINT_ERROR("Allocation of virtual device %s failed", @@ -3406,6 +3423,7 @@ static int vdev_create(struct scst_dev_type *devt, TRACE_DBG("usn %s", virt_dev->usn); *res_virt_dev = virt_dev; + res = 0; out: return res; @@ -3422,25 +3440,6 @@ static void vdev_destroy(struct scst_vdisk_dev *virt_dev) return; } -/* scst_vdisk_mutex supposed to be held */ -static struct scst_vdisk_dev *vdev_find(const char *name) -{ - struct scst_vdisk_dev *res, *vv; - - TRACE_ENTRY(); - - res = NULL; - list_for_each_entry(vv, &vdev_list, vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - res = vv; - break; - } - } - - TRACE_EXIT_HRES((unsigned long)res); - return res; -} - #ifndef CONFIG_SCST_PROC static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, @@ -4661,7 +4660,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, { int res = 0, action; char *p, *name, *filename, *i_buf, *t10_dev_id; - struct scst_vdisk_dev *virt_dev, *vv; + struct scst_vdisk_dev *virt_dev; uint32_t block_size = DEF_DISK_BLOCKSIZE; int block_shift = DEF_DISK_BLOCKSIZE_SHIFT; size_t slen; @@ -4724,21 +4723,6 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, if (action == 1) { /* open */ - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, - vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } - if (virt_dev) { - PRINT_ERROR("Virtual device with name " - "%s already exist", name); - res = -EINVAL; - goto out_up; - } - while (isspace(*p) && *p != '\0') p++; filename = p; @@ -4862,14 +4846,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, vdev_get_filename(virt_dev), virt_dev->virt_id, virt_dev->block_size); } else if (action == 0) { /* close */ - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, - vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } + virt_dev = vdev_find(name); if (virt_dev == NULL) { PRINT_ERROR("Device %s not found", name); res = -EINVAL; @@ -4877,14 +4854,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, } vdev_del_device(virt_dev); } else if (action == 2) { /* resync_size */ - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, - vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } + virt_dev = vdev_find(name); if (virt_dev == NULL) { PRINT_ERROR("Device %s not found", name); res = -EINVAL; @@ -4895,14 +4865,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset, if (res != 0) goto out_up; } else if (action == 3) { /* set T10 device id */ - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, - vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } + virt_dev = vdev_find(name); if (virt_dev == NULL) { PRINT_ERROR("Device %s not found", name); res = -EINVAL; @@ -4993,25 +4956,11 @@ out: /* scst_vdisk_mutex supposed to be held */ static int vcdrom_open(char *p, char *name) { - struct scst_vdisk_dev *virt_dev, *vv; + struct scst_vdisk_dev *virt_dev; char *filename; int res = 0; int cdrom_empty; - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } - if (virt_dev) { - PRINT_ERROR("Virtual device with name " - "%s already exist", name); - res = -EINVAL; - goto out; - } - while (isspace(*p) && *p != '\0') p++; filename = p; @@ -5076,17 +5025,10 @@ out_free_vdev: /* scst_vdisk_mutex supposed to be held */ static int vcdrom_close(char *name) { - struct scst_vdisk_dev *virt_dev, *vv; + struct scst_vdisk_dev *virt_dev; int res = 0; - virt_dev = NULL; - list_for_each_entry(vv, &vdev_list, vdev_list_entry) { - if (strcmp(vv->name, name) == 0) { - virt_dev = vv; - break; - } - } - + virt_dev = vdev_find(name); if (virt_dev == NULL) { PRINT_ERROR("Virtual device with name " "%s not found", name); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 514a07991..37043611f 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -4009,11 +4009,18 @@ void scst_free_session(struct scst_session *sess) scst_sess_free_tgt_devs(sess); -#ifndef CONFIG_SCST_PROC mutex_unlock(&scst_mutex); + +#ifndef CONFIG_SCST_PROC scst_sess_sysfs_del(sess); - mutex_lock(&scst_mutex); #endif + if (sess->unreg_done_fn) { + TRACE_DBG("Calling unreg_done_fn(%p)", sess); + sess->unreg_done_fn(sess); + TRACE_DBG("%s", "unreg_done_fn() returned"); + } + + mutex_lock(&scst_mutex); /* * The lists delete must be after sysfs del. Otherwise it would break @@ -4064,11 +4071,6 @@ void scst_free_session_callback(struct scst_session *sess) sess->shut_phase = SCST_SESS_SPH_UNREG_DONE_CALLING; mutex_unlock(&scst_mutex); - if (sess->unreg_done_fn) { - TRACE_DBG("Calling unreg_done_fn(%p)", sess); - sess->unreg_done_fn(sess); - TRACE_DBG("%s", "unreg_done_fn() returned"); - } scst_free_session(sess); if (c) diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 689ffa691..6a207cfab 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -1183,7 +1183,8 @@ static int scst_pr_check_pr_path(void) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) res = path_lookup(SCST_PR_DIR, 0, &nd); - scst_pr_path_put(&nd); + if (res == 0) + scst_pr_path_put(&nd); #else res = kern_path(SCST_PR_DIR, 0, &path); if (res == 0)