Author: mav
Date: Sat Nov 16 15:26:56 2013
New Revision: 258222
URL: http://svnweb.freebsd.org/changeset/base/258222

Log:
  MFC r249065 (by trasz):
  Fix locking problem in ctl_maintenance_in() - one cannot use M_WAITOK or call
  ctl_done() with mutex held.

Modified:
  stable/9/sys/cam/ctl/ctl.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/cam/ctl/ctl.c
==============================================================================
--- stable/9/sys/cam/ctl/ctl.c  Sat Nov 16 15:04:49 2013        (r258221)
+++ stable/9/sys/cam/ctl/ctl.c  Sat Nov 16 15:26:56 2013        (r258222)
@@ -6924,7 +6924,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;
@@ -6939,7 +6939,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,
@@ -6952,7 +6951,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;
@@ -6988,9 +6991,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];
@@ -7003,7 +7004,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;
@@ -7033,7 +7034,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;
@@ -7054,8 +7055,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",
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "[email protected]"

Reply via email to