mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
scst_local: Fix a race condition
Avoid that the following crash can occur: general protection fault: 0000 [#1] PREEMPT SMP RIP: 0010:scsi_is_host_device+0x7/0x20 [scsi_mod] Call Trace: scst_process_aens+0x95/0x1d0 [scst_local] scst_aen_work_fn+0x6f/0x120 [scst_local] process_one_work+0x20b/0x6c0 worker_thread+0x4e/0x4a0 kthread+0x113/0x150 ret_from_fork+0x31/0x40 git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7185 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1265,6 +1265,7 @@ static void scst_process_aens(struct scst_local_sess *sess,
|
||||
__acquires(&sess->aen_lock)
|
||||
{
|
||||
struct scst_aen_work_item *work_item = NULL;
|
||||
struct Scsi_Host *shost;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -1274,7 +1275,9 @@ static void scst_process_aens(struct scst_local_sess *sess,
|
||||
work_item = list_first_entry(&sess->aen_work_list,
|
||||
struct scst_aen_work_item, work_list_entry);
|
||||
list_del(&work_item->work_list_entry);
|
||||
|
||||
shost = sess->shost;
|
||||
if (shost && !scsi_host_get(shost))
|
||||
shost = NULL;
|
||||
spin_unlock(&sess->aen_lock);
|
||||
|
||||
if (cleanup_only)
|
||||
@@ -1283,13 +1286,17 @@ static void scst_process_aens(struct scst_local_sess *sess,
|
||||
sBUG_ON(work_item->aen->event_fn != SCST_AEN_SCSI);
|
||||
|
||||
/* Let's always rescan */
|
||||
scsi_scan_target(&sess->shost->shost_gendev, 0, 0,
|
||||
SCAN_WILD_CARD, 1);
|
||||
if (shost)
|
||||
scsi_scan_target(&shost->shost_gendev, 0, 0,
|
||||
SCAN_WILD_CARD, 1);
|
||||
|
||||
done:
|
||||
scst_aen_done(work_item->aen);
|
||||
kfree(work_item);
|
||||
|
||||
if (shost)
|
||||
scsi_host_put(shost);
|
||||
|
||||
spin_lock(&sess->aen_lock);
|
||||
}
|
||||
|
||||
@@ -1707,12 +1714,18 @@ out:
|
||||
static int scst_local_driver_remove(struct device *dev)
|
||||
{
|
||||
struct scst_local_sess *sess;
|
||||
struct Scsi_Host *shost = NULL;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sess = to_scst_lcl_sess(dev);
|
||||
scsi_remove_host(sess->shost);
|
||||
scsi_host_put(sess->shost);
|
||||
|
||||
spin_lock(&sess->aen_lock);
|
||||
swap(sess->shost, shost);
|
||||
spin_unlock(&sess->aen_lock);
|
||||
|
||||
scsi_remove_host(shost);
|
||||
scsi_host_put(shost);
|
||||
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user