scst: Fix race between closing a session and adding a LUN

Fixes this call stack (kernel 3.2.15):
WARNING: at lib/kref.c:34 kref_get+0x2d/0x30()
Hardware name: X8ST3
Modules linked in: scst_vdisk ib_srpt scst
Pid: 2159, comm: scst_uid Tainted: G W 3.2.15-07+ #2
Call Trace:
[<ffffffff81059cba>] warn_slowpath_common+0x7a/0xb0
[<ffffffff81059d05>] warn_slowpath_null+0x15/0x20
[<ffffffff812a5d7d>] kref_get+0x2d/0x30
[<ffffffff812a46ba>] kobject_get+0x1a/0x30
[<ffffffff812a471b>] kobject_add_internal+0x4b/0x240
[<ffffffff812a4bf3>] kobject_init_and_add+0x63/0x90
[<ffffffffa001082b>] ? scst_tgt_dev_setup_threads+0xab/0x310 [scst]
[<ffffffffa001a722>] scst_tgt_dev_sysfs_create+0x42/0x80 [scst]
[<ffffffffa0010e8c>] scst_alloc_add_tgt_dev+0x31c/0x4b0 [scst]
[<ffffffffa001362e>] scst_acg_add_lun+0xfe/0x230 [scst]
[<ffffffff812b4511>] ? _kstrtoull+0x31/0x90
[<ffffffffa001777c>] scst_luns_mgmt_store_work_fn+0x29c/0x6b0 [scst]
[<ffffffffa0019634>] sysfs_work_thread_fn+0xd4/0x2e0 [scst]
[<ffffffff8107a020>] ? wake_up_bit+0x40/0x40
[<ffffffffa0019560>] ? scst_tgt_cpu_mask_show+0x20/0x20 [scst]
[<ffffffff81079ab6>] kthread+0x96/0xa0
[<ffffffff8163d7b4>] kernel_thread_helper+0x4/0x10
[<ffffffff81079a20>] ? kthread_worker_fn+0x190/0x190
[<ffffffff8163d7b0>] ? gs_change+0x13/0x13

Reported-by: Sebastian Riemer <sebastian.riemer@profitbricks.com>


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4453 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2012-08-07 17:29:58 +00:00
parent 736b99485d
commit 239d6243ec
+4 -10
View File
@@ -5093,6 +5093,10 @@ void scst_free_session(struct scst_session *sess)
mutex_lock(&scst_mutex);
scst_sess_free_tgt_devs(sess);
TRACE_DBG("Removing sess %p from the list", sess);
list_del(&sess->sess_list_entry);
TRACE_DBG("Removing session %p from acg %s", sess, sess->acg->acg_name);
list_del(&sess->acg_sess_list_entry);
mutex_unlock(&scst_mutex);
@@ -5107,16 +5111,6 @@ void scst_free_session(struct scst_session *sess)
mutex_lock(&scst_mutex);
/*
* The lists delete must be after sysfs del. Otherwise it would break
* logic in scst_sess_sysfs_create() to avoid duplicate sysfs names.
*/
TRACE_DBG("Removing sess %p from the list", sess);
list_del(&sess->sess_list_entry);
TRACE_DBG("Removing session %p from acg %s", sess, sess->acg->acg_name);
list_del(&sess->acg_sess_list_entry);
/* Called under lock to protect from too early tgt release */
wake_up_all(&sess->tgt->unreg_waitQ);