summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <mchristi@redhat.com>2017-06-23 08:18:20 +0200
committerNicholas Bellinger <nab@linux-iscsi.org>2017-07-07 08:11:42 +0200
commit9260695d65590f4711d1166eadbfcb0acfa0625a (patch)
treea5578a39bf795f15434f557a7b716dd40fe1abe5 /drivers
parenttcmu: drop configured check in destroy (diff)
downloadlinux-9260695d65590f4711d1166eadbfcb0acfa0625a.tar.xz
linux-9260695d65590f4711d1166eadbfcb0acfa0625a.zip
tcmu: fix multiple uio open/close sequences
If the uio device is open and closed multiple times, the kref count will be off due to tcmu_release getting called multiple times for each close. This patch integrates Wenji Tang's patch to add a kref_get on open that now matches the kref_put done on tcmu_release and adds a kref_put in tcmu_destroy_device to match the kref_get done in succesful tcmu_configure_device calls. Signed-off-by: Mike Christie <mchristi@redhat.com> Cc: Wenji Tang <tang.wenji@zte.com.cn> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/target/target_core_user.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index d10aa0ac0918..1e69b1b32558 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1269,6 +1269,7 @@ static int tcmu_open(struct uio_info *info, struct inode *inode)
return -EBUSY;
udev->inode = inode;
+ kref_get(&udev->kref);
pr_debug("open\n");
@@ -1300,7 +1301,7 @@ static int tcmu_release(struct uio_info *info, struct inode *inode)
clear_bit(TCMU_DEV_BIT_OPEN, &udev->flags);
pr_debug("close\n");
- /* release ref from configure */
+ /* release ref from open */
kref_put(&udev->kref, tcmu_dev_kref_release);
return 0;
}
@@ -1596,6 +1597,9 @@ static void tcmu_destroy_device(struct se_device *dev)
tcmu_netlink_event(udev, TCMU_CMD_REMOVED_DEVICE, 0, NULL);
uio_unregister_device(&udev->uio_info);
+
+ /* release ref from configure */
+ kref_put(&udev->kref, tcmu_dev_kref_release);
}
enum {