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 <yanb@mellanox.com>

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/iser@6002 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Yan Burman
2015-01-28 12:16:05 +00:00
parent 06e42a7273
commit 4a8b416ff8
2 changed files with 11 additions and 6 deletions

View File

@@ -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"

View File

@@ -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);