Some locking cleanups
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Mon, 30 Nov 2009 19:17:59 +0000 (19:17 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Mon, 30 Nov 2009 19:17:59 +0000 (19:17 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@1373 d57e44dd-8a1f-0410-8b47-8ef2f437770f

qla2x00t/qla2x00-target/qla2x00t.c
scst/include/scst.h
scst/src/dev_handlers/scst_vdisk.c
scst/src/scst_sysfs.c

index 798ee50..f691f8f 100644 (file)
@@ -793,7 +793,7 @@ static inline int test_tgt_sess_count(struct q2t_tgt *tgt)
        return res;
 }
 
-/* Must be called under tgt_host_action_mutex */
+/* Must be called under tgt_host_action_mutex or q2t_unreg_rwsem write locked */
 static void q2t_target_stop(struct scst_tgt *scst_tgt)
 {
        struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
@@ -859,7 +859,7 @@ static void q2t_target_stop(struct scst_tgt *scst_tgt)
        return;
 }
 
-/* Must be called under tgt_host_action_mutex */
+/* Must be called under tgt_host_action_mutex or q2t_unreg_rwsem write locked */
 static int q2t_target_release(struct scst_tgt *scst_tgt)
 {
        struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
index a0558bc..ac84fbd 100644 (file)
@@ -1063,10 +1063,7 @@ struct scst_dev_type {
        /* Optional sysfs attributes */
        const struct attribute **devt_attrs;
 
-       /*
-        * Optional sysfs device attributes. They are serialized
-        * by dev_sysfs_mutex.
-        */
+       /* Optional sysfs device attributes */
        const struct attribute **dev_attrs;
 #endif
 
@@ -1817,9 +1814,6 @@ struct scst_device {
         */
        struct rw_semaphore dev_attr_rwsem;
 
-       /* Used to serialize all the device sysfs calls */
-       struct mutex dev_sysfs_mutex;
-
        struct kobject dev_kobj; /* kobject for this struct */
        struct kobject *dev_exp_kobj; /* exported groups */
 
index 8685ba8..1654765 100644 (file)
@@ -219,6 +219,8 @@ struct scst_vdisk_dev {
        struct scst_device *dev;
        struct list_head vdisk_dev_list_entry;
 
+       struct mutex vdev_sysfs_mutex;
+
        const struct vdev_type *vdt;
 };
 
@@ -2956,28 +2958,28 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
        loff_t file_size;
        int res = 0;
 
-       /*
-        * There's no need in any lock here, because SCST core serializes
-        * all device sysfs calls.
-        */
+       if (mutex_lock_interruptible(&virt_dev->vdev_sysfs_mutex) != 0) {
+               res = -EINTR;
+               goto out;
+       }
 
        if (!virt_dev->nullio) {
                res = vdisk_get_file_size(virt_dev->file_name,
                                virt_dev->blockio, &file_size);
                if (res != 0)
-                       goto out;
+                       goto out_unlock;
        } else
                file_size = VDISK_NULLIO_SIZE;
 
        if (file_size == virt_dev->file_size) {
                PRINT_INFO("Size of virtual disk %s remained the same",
                        virt_dev->name);
-               goto out;
+               goto out_unlock;
        }
 
        res = scst_suspend_activity(true);
        if (res != 0)
-               goto out;
+               goto out_unlock;
 
        virt_dev->file_size = file_size;
        virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
@@ -2997,6 +2999,9 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
 
        scst_resume_activity();
 
+out_unlock:
+       mutex_unlock(&virt_dev->vdev_sysfs_mutex);
+
 out:
        return res;
 }
@@ -3005,6 +3010,7 @@ static void vdev_init(struct vdev_type *vdt, struct scst_vdisk_dev *virt_dev)
 {
        memset(virt_dev, 0, sizeof(*virt_dev));
        spin_lock_init(&virt_dev->flags_lock);
+       mutex_init(&virt_dev->vdev_sysfs_mutex);
        virt_dev->vdt = vdt;
 
        virt_dev->block_size = DEF_DISK_BLOCKSIZE;
@@ -3451,11 +3457,6 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
 
        TRACE_ENTRY();
 
-       /*
-        * There's no need in any lock here, because SCST core serializes
-        * all device sysfs calls.
-        */
-
        i_buf = kmalloc(length+1, GFP_KERNEL);
        if (i_buf == NULL) {
                PRINT_ERROR("Unable to alloc intermediate buffer with size %d",
@@ -3479,9 +3480,14 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
        }
        *pp = '\0';
 
+       if (mutex_lock_interruptible(&virt_dev->vdev_sysfs_mutex) != 0) {
+               res = -EINTR;
+               goto out_free;
+       }
+
        res = scst_suspend_activity(true);
        if (res != 0)
-               goto out;
+               goto out_sysfs_unlock;
 
        /* To sync with detach*() functions */
        mutex_lock(&scst_mutex);
@@ -3515,7 +3521,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
                res = vdisk_get_file_size(virt_dev->file_name,
                                virt_dev->blockio, &err);
                if (res != 0)
-                       goto out_free;
+                       goto out_free_fn;
        } else {
                err = 0;
                virt_dev->file_name = NULL;
@@ -3525,7 +3531,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
                PRINT_ERROR("Prevent medium removal for "
                        "virtual device with name %s", virt_dev->name);
                res = -EINVAL;
-               goto out_free;
+               goto out_free_fn;
        }
 
        virt_dev->file_size = err;
@@ -3556,11 +3562,17 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
 out_resume:
        scst_resume_activity();
 
+out_sysfs_unlock:
+       mutex_unlock(&virt_dev->vdev_sysfs_mutex);
+
+out_free:
+       kfree(i_buf);
+
 out:
        TRACE_EXIT_RES(res);
        return res;
 
-out_free:
+out_free_fn:
        kfree(virt_dev->file_name);
        virt_dev->file_name = old_fn;
 
@@ -3721,8 +3733,16 @@ static ssize_t vdisk_sysfs_size_show(struct kobject *kobj,
        dev = container_of(kobj, struct scst_device, dev_kobj);
        virt_dev = (struct scst_vdisk_dev *)dev->dh_priv;
 
+       if (mutex_lock_interruptible(&virt_dev->vdev_sysfs_mutex) != 0) {
+               pos = -EINTR;
+               goto out;
+       }
+
        pos = sprintf(buf, "%lld\n", virt_dev->file_size);
 
+       mutex_unlock(&virt_dev->vdev_sysfs_mutex);
+
+out:
        TRACE_EXIT_RES(pos);
        return pos;
 }
@@ -3847,8 +3867,16 @@ static ssize_t vdisk_sysfs_filename_show(struct kobject *kobj,
        dev = container_of(kobj, struct scst_device, dev_kobj);
        virt_dev = (struct scst_vdisk_dev *)dev->dh_priv;
 
+       if (mutex_lock_interruptible(&virt_dev->vdev_sysfs_mutex) != 0) {
+               pos = -EINTR;
+               goto out;
+       }
+
        pos = sprintf(buf, "%s\n", virt_dev->file_name);
 
+       mutex_unlock(&virt_dev->vdev_sysfs_mutex);
+
+out:
        TRACE_EXIT_RES(pos);
        return pos;
 }
index 310729e..ac5772a 100644 (file)
@@ -654,17 +654,10 @@ static ssize_t scst_dev_attr_show(struct kobject *kobj, struct attribute *attr,
                goto out;
        }
 
-       if (mutex_lock_interruptible(&dev->dev_sysfs_mutex) != 0) {
-               res = -EINTR;
-               goto out;
-       }
-
        kobj_attr = container_of(attr, struct kobj_attribute, attr);
 
        res = kobj_attr->show(kobj, kobj_attr, buf);
 
-       mutex_unlock(&dev->dev_sysfs_mutex);
-
        up_read(&dev->dev_attr_rwsem);
 
 out:
@@ -685,17 +678,10 @@ static ssize_t scst_dev_attr_store(struct kobject *kobj, struct attribute *attr,
                goto out;
        }
 
-       if (mutex_lock_interruptible(&dev->dev_sysfs_mutex) != 0) {
-               res = -EINTR;
-               goto out;
-       }
-
        kobj_attr = container_of(attr, struct kobj_attribute, attr);
 
        res = kobj_attr->store(kobj, kobj_attr, buf, count);
 
-       mutex_unlock(&dev->dev_sysfs_mutex);
-
        up_read(&dev->dev_attr_rwsem);
 
 out:
@@ -720,7 +706,6 @@ int scst_create_device_sysfs(struct scst_device *dev)
        TRACE_ENTRY();
 
        init_rwsem(&dev->dev_attr_rwsem);
-       mutex_init(&dev->dev_sysfs_mutex);
 
        dev->dev_kobj_initialized = 1;