mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-19 05:36:22 +00:00
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:
+13
-1
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user