From 287def71413305554df0ed429519c6c586e813a8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 3 Nov 2012 13:56:12 +0000 Subject: [PATCH] scst_local: Avoid deadlock during module removal with kernel 3.6 (merge r4566 from trunk) git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@4575 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst_local/scst_local.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index 848da81a5..8270cf8fe 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -948,6 +948,12 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt, sess = to_scst_lcl_sess(scsi_get_device(SCpnt->device->host)); + if (sess->unregistering) { + SCpnt->result = DID_BAD_TARGET << 16; + SCpnt->scsi_done(SCpnt); + return 0; + } + scsi_set_resid(SCpnt, 0); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) @@ -1585,7 +1591,7 @@ static void scst_local_release_adapter(struct device *dev) goto out; spin_lock(&sess->aen_lock); - sess->unregistering = 1; + WARN_ON_ONCE(!sess->unregistering); scst_process_aens(sess, true); spin_unlock(&sess->aen_lock); @@ -1776,6 +1782,10 @@ static void __scst_local_remove_target(struct scst_local_tgt *tgt) list_for_each_entry_safe(sess, ts, &tgt->sessions_list, sessions_list_entry) { + spin_lock(&sess->aen_lock); + sess->unregistering = 1; + spin_unlock(&sess->aen_lock); + scst_local_remove_adapter(sess); }