From 4a8b416ff8297819cc5ddbc67e89a75a709adcfe Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Wed, 28 Jan 2015 12:16:05 +0000 Subject: [PATCH] isert: Make sure we have a valid conn pointer Fix a race where disconnect was called while iscsi-scstd was doing ioctls Signed-off-by: Yan Burman git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/iser@6002 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/isert-scst/isert.h | 3 +++ iscsi-scst/kernel/isert-scst/isert_login.c | 14 ++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/iscsi-scst/kernel/isert-scst/isert.h b/iscsi-scst/kernel/isert-scst/isert.h index c083d536d..af7c713af 100644 --- a/iscsi-scst/kernel/isert-scst/isert.h +++ b/iscsi-scst/kernel/isert-scst/isert.h @@ -92,6 +92,8 @@ enum isert_conn_dev_state { CS_DISCONNECTED, }; +#define ISERT_CONN_PASSED 0 + struct isert_conn_dev { struct device *dev; struct cdev cdev; @@ -116,6 +118,7 @@ struct isert_conn_dev { struct timer_list tmo_timer; int timer_active; struct kref kref; + unsigned long flags; }; #define ISER_CONN_DEV_PREFIX "isert/conn" diff --git a/iscsi-scst/kernel/isert-scst/isert_login.c b/iscsi-scst/kernel/isert-scst/isert_login.c index 80ebfdda9..35c094433 100644 --- a/iscsi-scst/kernel/isert-scst/isert_login.c +++ b/iscsi-scst/kernel/isert-scst/isert_login.c @@ -102,6 +102,8 @@ static void isert_kref_release_dev(struct kref *kref) atomic_set(&dev->available, 1); if (!list_is_singular(&dev->conn_list_entry)) list_del_init(&dev->conn_list_entry); + dev->flags = 0; + dev->conn = NULL; } static void isert_dev_release(struct isert_conn_dev *dev) @@ -219,7 +221,7 @@ int isert_conn_alloc(struct iscsi_session *session, &session->tgt_params); if (!res) - dev->conn = NULL; + set_bit(ISERT_CONN_PASSED, &dev->flags); fput(filp); @@ -301,9 +303,10 @@ static int isert_listen_open(struct inode *inode, struct file *filp) static void isert_delete_conn_dev(struct isert_conn_dev *conn_dev) { isert_del_timer(conn_dev); - if (conn_dev->conn) { + + if (!test_and_set_bit(ISERT_CONN_PASSED, &conn_dev->flags)) { + BUG_ON(conn_dev->conn == NULL); isert_close_connection(conn_dev->conn); - conn_dev->conn = NULL; } list_del(&conn_dev->conn_list_entry); } @@ -452,7 +455,6 @@ int isert_connection_closed(struct iscsi_conn *iscsi_conn) spin_unlock(&dev->pdu_lock); } - dev->conn = NULL; wake_up(&dev->waitqueue); isert_dev_release(dev); } @@ -521,9 +523,9 @@ static int isert_release(struct inode *inode, struct file *filp) dev->sg_virt = NULL; dev->is_discovery = 0; - if (dev->conn) { + if (!test_and_set_bit(ISERT_CONN_PASSED, &dev->flags)) { + BUG_ON(dev->conn == NULL); isert_close_connection(dev->conn); - dev->conn = NULL; } isert_del_timer(dev);