mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-19 11:41:26 +00:00
isert: Fix race between disconnect handler and read by iscsi-scstd (merge r5896 from trunk)
git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.0.x-iser@6005 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -91,29 +91,23 @@ static void isert_del_timer(struct isert_conn_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void release_dev(struct isert_conn_dev *dev)
|
||||
{
|
||||
kref_init(&dev->kref);
|
||||
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
dev->occupied = 0;
|
||||
list_del_init(&dev->conn_list_entry);
|
||||
dev->state = CS_INIT;
|
||||
atomic_set(&dev->available, 1);
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
}
|
||||
|
||||
static void isert_kref_release_dev(struct kref *kref)
|
||||
{
|
||||
struct isert_conn_dev *dev = container_of(kref,
|
||||
struct isert_conn_dev,
|
||||
kref);
|
||||
release_dev(dev);
|
||||
kref_init(&dev->kref);
|
||||
dev->occupied = 0;
|
||||
list_del_init(&dev->conn_list_entry);
|
||||
dev->state = CS_INIT;
|
||||
atomic_set(&dev->available, 1);
|
||||
}
|
||||
|
||||
static void isert_dev_release(struct isert_conn_dev *dev)
|
||||
{
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
kref_put(&dev->kref, isert_kref_release_dev);
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
|
||||
@@ -338,6 +332,7 @@ static ssize_t isert_listen_read(struct file *filp, char __user *buf,
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (!have_new_connection(dev)) {
|
||||
wait_for_connection:
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
res = wait_event_freezable(dev->waitqueue,
|
||||
@@ -346,9 +341,12 @@ static ssize_t isert_listen_read(struct file *filp, char __user *buf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
sBUG_ON(list_empty(&dev->new_conn_list));
|
||||
|
||||
spin_lock(&dev->conn_lock);
|
||||
if (list_empty(&dev->new_conn_list)) {
|
||||
/* could happen if we got disconnect */
|
||||
spin_unlock(&dev->conn_lock);
|
||||
goto wait_for_connection;
|
||||
}
|
||||
conn_dev = list_first_entry(&dev->new_conn_list, struct isert_conn_dev,
|
||||
conn_list_entry);
|
||||
list_move(&conn_dev->conn_list_entry, &dev->curr_conn_list);
|
||||
|
||||
Reference in New Issue
Block a user