svn commit: r249065 - head/sys/cam/ctl

Edward Tomasz Napierala trasz at FreeBSD.org
Wed Apr 3 20:26:54 UTC 2013


Author: trasz
Date: Wed Apr  3 20:26:52 2013
New Revision: 249065
URL: http://svnweb.freebsd.org/changeset/base/249065

Log:
  Fix locking problem in ctl_maintenance_in() - one cannot use M_WAITOK or call
  ctl_done() with mutex held.
  
  Reviewed by:	ken
  Sponsored by:	FreeBSD Foundation

Modified:
  head/sys/cam/ctl/ctl.c

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Wed Apr  3 19:26:32 2013	(r249064)
+++ head/sys/cam/ctl/ctl.c	Wed Apr  3 20:26:52 2013	(r249065)
@@ -6926,7 +6926,7 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 	struct scsi_maintenance_in *cdb;
 	int retval;
 	int alloc_len, total_len = 0;
-	int num_target_port_groups;
+	int num_target_port_groups, single;
 	struct ctl_lun *lun;
 	struct ctl_softc *softc;
 	struct scsi_target_group_data *rtg_ptr;
@@ -6941,7 +6941,6 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 	lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
 
 	retval = CTL_RETVAL_COMPLETE;
-	mtx_lock(&softc->ctl_lock);
 
 	if ((cdb->byte2 & SERVICE_ACTION_MASK) != SA_RPRT_TRGT_GRP) {
 		ctl_set_invalid_field(/*ctsio*/ ctsio,
@@ -6954,7 +6953,11 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 		return(retval);
 	}
 
-	if (ctl_is_single)
+	mtx_lock(&softc->ctl_lock);
+	single = ctl_is_single;
+	mtx_unlock(&softc->ctl_lock);
+
+	if (single)
         	num_target_port_groups = NUM_TARGET_PORT_GROUPS - 1;
 	else
         	num_target_port_groups = NUM_TARGET_PORT_GROUPS;
@@ -6990,9 +6993,7 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 	tp_desc_ptr1_2 = (struct scsi_target_port_descriptor *)
 	        &tp_desc_ptr1_1->desc_list[0];
 
-
-
-	if (ctl_is_single == 0) {
+	if (single == 0) {
 		tpg_desc_ptr2 = (struct scsi_target_port_group_descriptor *)
 	                &tp_desc_ptr1_2->desc_list[0];
 		tp_desc_ptr2_1 = &tpg_desc_ptr2->descriptors[0];
@@ -7005,7 +7006,7 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 	}
 
 	scsi_ulto4b(total_len - 4, rtg_ptr->length);
-	if (ctl_is_single == 0) {
+	if (single == 0) {
         	if (ctsio->io_hdr.nexus.targ_port < CTL_MAX_PORTS) {
 			if (lun->flags & CTL_LUN_PRIMARY_SC) {
 				tpg_desc_ptr1->pref_state = TPG_PRIMARY;
@@ -7035,7 +7036,7 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 	tpg_desc_ptr1->status = TPG_IMPLICIT;
 	tpg_desc_ptr1->target_port_count= NUM_PORTS_PER_GRP;
 
-	if (ctl_is_single == 0) {
+	if (single == 0) {
 		tpg_desc_ptr2->support = 0;
 		tpg_desc_ptr2->target_port_group[1] = 2;
 		tpg_desc_ptr2->status = TPG_IMPLICIT;
@@ -7056,8 +7057,6 @@ ctl_maintenance_in(struct ctl_scsiio *ct
 		}
 	}
 
-	mtx_unlock(&softc->ctl_lock);
-
 	ctsio->be_move_done = ctl_config_move_done;
 
 	CTL_DEBUG_PRINT(("buf = %x %x %x %x %x %x %x %x\n",


More information about the svn-src-head mailing list