Followup for r1361

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1364 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2009-11-27 18:22:45 +00:00
parent e6f5aa8865
commit 1de649c263
5 changed files with 48 additions and 7 deletions
+13 -1
View File
@@ -1063,7 +1063,10 @@ struct scst_dev_type {
/* Optional sysfs attributes */
const struct attribute **devt_attrs;
/* Optional sysfs device attributes */
/*
* Optional sysfs device attributes. They are serialized
* by dev_sysfs_mutex.
*/
const struct attribute **dev_attrs;
#endif
@@ -1145,6 +1148,9 @@ struct scst_tgt {
/* Set if tgt_kobj was initialized */
unsigned int tgt_kobj_initialized:1;
/* Set if scst_tgt_sysfs_prepare_put() was called for tgt_kobj */
unsigned int tgt_kobj_put_prepared:1;
/*
* Used to protect sysfs attributes to be called after this
* object was unregistered.
@@ -3218,6 +3224,12 @@ struct scst_trace_log {
const char *token;
};
/*
* Main SCST mutex. All targets, devices and dev_types management is done
* under this mutex.
*/
extern struct mutex scst_mutex;
#ifdef CONFIG_SCST_PROC
/*
+14 -4
View File
@@ -212,7 +212,8 @@ struct scst_vdisk_dev {
int virt_id;
char name[16+1]; /* Name of the virtual device,
must be <= SCSI Model + 1 */
char *file_name; /* File name */
char *file_name; /* File name, protected by
scst_mutex and suspended activities */
char usn[MAX_USN_LEN];
struct scst_device *dev;
struct list_head vdisk_dev_list_entry;
@@ -815,7 +816,8 @@ out:
*
* Returns : None
*
* Description: Called to detach this device type driver
* Description: Called to detach this device type driver.
* Scst_mutex supposed to be held.
************************************************************/
static void vdisk_detach(struct scst_device *dev)
{
@@ -3457,6 +3459,9 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
if (res != 0)
goto out;
/* To sync with detach*() functions */
mutex_lock(&scst_mutex);
if (*file_name == '\0') {
virt_dev->cdrom_empty = 1;
TRACE_DBG("%s", "No media");
@@ -3464,7 +3469,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
PRINT_ERROR("File path \"%s\" is not "
"absolute", file_name);
res = -EINVAL;
goto out_resume;
goto out_unlock;
} else
virt_dev->cdrom_empty = 0;
@@ -3477,7 +3482,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
TRACE(TRACE_OUT_OF_MEM, "%s",
"Allocation of file_name failed");
res = -ENOMEM;
goto out_resume;
goto out_unlock;
}
strncpy(fn, file_name, len);
@@ -3504,6 +3509,8 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
if (!virt_dev->cdrom_empty)
virt_dev->media_changed = 1;
mutex_unlock(&scst_mutex);
scst_dev_del_all_thr_data(virt_dev->dev);
if (!virt_dev->cdrom_empty) {
@@ -3532,6 +3539,9 @@ out:
out_free:
kfree(virt_dev->file_name);
virt_dev->file_name = old_fn;
out_unlock:
mutex_unlock(&scst_mutex);
goto out_resume;
}
+3
View File
@@ -79,6 +79,7 @@
* flush_scheduled_work().
*/
struct mutex scst_mutex;
EXPORT_SYMBOL(scst_mutex);
/* All 3 protected by scst_mutex */
struct list_head scst_template_list;
@@ -494,6 +495,8 @@ void scst_unregister(struct scst_tgt *tgt)
TRACE_ENTRY();
scst_tgt_sysfs_prepare_put(tgt);
TRACE_DBG("%s", "Calling target driver's release()");
tgt->tgtt->release(tgt);
TRACE_DBG("%s", "Target driver's release() returned");
+2 -1
View File
@@ -144,7 +144,6 @@ extern spinlock_t scst_main_lock;
extern struct scst_sgv_pools scst_sgv;
extern unsigned long scst_flags;
extern struct mutex scst_mutex;
extern atomic_t scst_cmd_count;
extern struct list_head scst_template_list;
extern struct list_head scst_dev_list;
@@ -443,6 +442,7 @@ static inline int scst_create_tgt_sysfs(struct scst_tgt *tgt)
{
return 0;
}
static inline void scst_tgt_sysfs_prepare_put(struct scst_tgt *tgt) { }
static inline void scst_tgt_sysfs_put(struct scst_tgt *tgt)
{
scst_free_tgt(tgt);
@@ -497,6 +497,7 @@ void scst_sysfs_cleanup(void);
int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt);
void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt);
int scst_create_tgt_sysfs(struct scst_tgt *tgt);
void scst_tgt_sysfs_prepare_put(struct scst_tgt *tgt);
void scst_tgt_sysfs_put(struct scst_tgt *tgt);
int scst_create_sess_sysfs(struct scst_session *sess);
void scst_sess_sysfs_put(struct scst_session *sess);
+16 -1
View File
@@ -484,6 +484,20 @@ out_nomem:
goto out;
}
/*
* Must not be called under scst_mutex or there can be a deadlock with
* tgt_attr_rwsem
*/
void scst_tgt_sysfs_prepare_put(struct scst_tgt *tgt)
{
if (tgt->tgt_kobj_initialized) {
down_write(&tgt->tgt_attr_rwsem);
tgt->tgt_kobj_put_prepared = 1;
}
return;
}
/*
* Must not be called under scst_mutex or there can be a deadlock with
* tgt_attr_rwsem
@@ -504,7 +518,8 @@ void scst_tgt_sysfs_put(struct scst_tgt *tgt)
kobject_del(&tgt->tgt_kobj);
down_write(&tgt->tgt_attr_rwsem);
if (!tgt->tgt_kobj_put_prepared)
down_write(&tgt->tgt_attr_rwsem);
kobject_put(&tgt->tgt_kobj);
} else
scst_free_tgt(tgt);