Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2019-03-20 12:44:25 +0100
committerHannes Reinecke <hare@suse.de>2019-03-20 12:44:29 +0100
commite1a0bf978d99c5bb59fa70d40b4feb014cc63bed (patch)
treea7b1cfddcdec9a1b8949595b4acdc73251954c07
parentf2b1f56b609581115ad84929f3c667bd94ba91a0 (diff)
ch: fixup refcounting imbalance for SCSI devices (bsc#1124235).
-rw-r--r--patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch67
-rw-r--r--series.conf1
2 files changed, 68 insertions, 0 deletions
diff --git a/patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch b/patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch
new file mode 100644
index 0000000000..76dc7fa250
--- /dev/null
+++ b/patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch
@@ -0,0 +1,67 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 20 Apr 2015 11:37:35 +0200
+Subject: [PATCH 2/2] ch: fixup refcounting imbalance for SCSI devices
+References: bsc#1124235
+Patch-Mainline: submitted linux-scsi 2019/03/20
+
+The SCSI device is required to be present during 'ch_probe'
+and ch_open(), but as we cannot known whether ch_release()
+or ch_remove() will be called first we should blank out the
+pointer to the SCSI device in ch_destroy(), not in ch_release().
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/ch.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
+index 8f426903d7e4..08acd896d4e2 100644
+--- a/drivers/scsi/ch.c
++++ b/drivers/scsi/ch.c
+@@ -568,6 +568,7 @@ static void ch_destroy(struct kref *ref)
+ {
+ scsi_changer *ch = container_of(ref, scsi_changer, ref);
+
++ ch->device = NULL;
+ kfree(ch->dt);
+ kfree(ch);
+ }
+@@ -579,7 +580,6 @@ ch_release(struct inode *inode, struct file *file)
+
+ mutex_lock(&ch_mutex);
+ scsi_device_put(ch->device);
+- ch->device = NULL;
+ file->private_data = NULL;
+ mutex_unlock(&ch_mutex);
+ kref_put(&ch->ref, ch_destroy);
+@@ -596,14 +596,17 @@ ch_open(struct inode *inode, struct file *file)
+ spin_lock(&ch_index_lock);
+ ch = idr_find(&ch_index_idr, minor);
+
+- if (NULL == ch || scsi_device_get(ch->device)) {
++ if (NULL == ch || kref_get_unless_zero(&ch->ref)) {
+ spin_unlock(&ch_index_lock);
+ mutex_unlock(&ch_mutex);
+ return -ENXIO;
+ }
+- kref_get(&ch->ref);
+ spin_unlock(&ch_index_lock);
+
++ if (!ch->device || scsi_device_get(ch->device)) {
++ kref_put(&ch->ref, ch_destroy);
++ return -ENXIO;
++ }
+ file->private_data = ch;
+ mutex_unlock(&ch_mutex);
+ return 0;
+@@ -976,6 +979,7 @@ static int ch_remove(struct device *dev)
+
+ spin_lock(&ch_index_lock);
+ idr_remove(&ch_index_idr, ch->minor);
++ dev_set_drvdata(dev, NULL);
+ spin_unlock(&ch_index_lock);
+
+ device_destroy(ch_sysfs_class, MKDEV(SCSI_CHANGER_MAJOR,ch->minor));
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 9d5fe4574f..1198b7474b 100644
--- a/series.conf
+++ b/series.conf
@@ -20966,6 +20966,7 @@
patches.arch/pseries-energy-Use-OF-accessor-function-to-read-ibm-.patch
patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch
patches.fixes/ch-add-missing-mutex_lock-mutex_unlock-in-ch_release.patch
+ patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch
########################################################
# end of sorted patches