From 24482f5d41d03b41ee5a750c3f466339cdb6b5d0 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 30 Nov 2009 19:17:59 +0000 Subject: [PATCH] Some locking cleanups git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1373 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t/qla2x00-target/qla2x00t.c | 4 +- scst/include/scst.h | 8 +--- scst/src/dev_handlers/scst_vdisk.c | 60 ++++++++++++++++++++++-------- scst/src/scst_sysfs.c | 15 -------- 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/qla2x00t/qla2x00-target/qla2x00t.c b/qla2x00t/qla2x00-target/qla2x00t.c index 798ee5033..f691f8f59 100644 --- a/qla2x00t/qla2x00-target/qla2x00t.c +++ b/qla2x00t/qla2x00-target/qla2x00t.c @@ -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); diff --git a/scst/include/scst.h b/scst/include/scst.h index a0558bcc1..ac84fbdbc 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -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 */ diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 8685ba8f9..1654765ae 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -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; } diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 310729e98..ac5772aab 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -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;