@@ -2731,24 +2731,16 @@ void scsi_start_queue(struct scsi_device *sdev)
27312731 blk_mq_unquiesce_queue (sdev -> request_queue );
27322732}
27332733
2734- static void scsi_stop_queue (struct scsi_device * sdev , bool nowait )
2734+ static void scsi_stop_queue (struct scsi_device * sdev )
27352735{
27362736 /*
27372737 * The atomic variable of ->queue_stopped covers that
27382738 * blk_mq_quiesce_queue* is balanced with blk_mq_unquiesce_queue.
27392739 *
2740- * However, we still need to wait until quiesce is done
2741- * in case that queue has been stopped.
2740+ * The caller needs to wait until quiesce is done.
27422741 */
2743- if (!cmpxchg (& sdev -> queue_stopped , 0 , 1 )) {
2744- if (nowait )
2745- blk_mq_quiesce_queue_nowait (sdev -> request_queue );
2746- else
2747- blk_mq_quiesce_queue (sdev -> request_queue );
2748- } else {
2749- if (!nowait )
2750- blk_mq_wait_quiesce_done (sdev -> request_queue -> tag_set );
2751- }
2742+ if (!cmpxchg (& sdev -> queue_stopped , 0 , 1 ))
2743+ blk_mq_quiesce_queue_nowait (sdev -> request_queue );
27522744}
27532745
27542746/**
@@ -2775,37 +2767,46 @@ int scsi_internal_device_block_nowait(struct scsi_device *sdev)
27752767 * request queue.
27762768 */
27772769 if (!ret )
2778- scsi_stop_queue (sdev , true );
2770+ scsi_stop_queue (sdev );
27792771 return ret ;
27802772}
27812773EXPORT_SYMBOL_GPL (scsi_internal_device_block_nowait );
27822774
27832775/**
2784- * scsi_internal_device_block - try to transition to the SDEV_BLOCK state
2776+ * scsi_device_block - try to transition to the SDEV_BLOCK state
27852777 * @sdev: device to block
2778+ * @data: dummy argument, ignored
27862779 *
2787- * Pause SCSI command processing on the specified device and wait until all
2788- * ongoing scsi_request_fn() / scsi_queue_rq() calls have finished. May sleep.
2789- *
2790- * Returns zero if successful or a negative error code upon failure.
2780+ * Pause SCSI command processing on the specified device. Callers must wait
2781+ * until all ongoing scsi_queue_rq() calls have finished after this function
2782+ * returns.
27912783 *
27922784 * Note:
27932785 * This routine transitions the device to the SDEV_BLOCK state (which must be
27942786 * a legal transition). When the device is in this state, command processing
27952787 * is paused until the device leaves the SDEV_BLOCK state. See also
27962788 * scsi_internal_device_unblock().
27972789 */
2798- static int scsi_internal_device_block (struct scsi_device * sdev )
2790+ static void scsi_device_block (struct scsi_device * sdev , void * data )
27992791{
28002792 int err ;
2793+ enum scsi_device_state state ;
28012794
28022795 mutex_lock (& sdev -> state_mutex );
28032796 err = __scsi_internal_device_block_nowait (sdev );
2797+ state = sdev -> sdev_state ;
28042798 if (err == 0 )
2805- scsi_stop_queue (sdev , false);
2799+ /*
2800+ * scsi_stop_queue() must be called with the state_mutex
2801+ * held. Otherwise a simultaneous scsi_start_queue() call
2802+ * might unquiesce the queue before we quiesce it.
2803+ */
2804+ scsi_stop_queue (sdev );
2805+
28062806 mutex_unlock (& sdev -> state_mutex );
28072807
2808- return err ;
2808+ WARN_ONCE (err , "%s: failed to block %s in state %d\n" ,
2809+ __func__ , dev_name (& sdev -> sdev_gendev ), state );
28092810}
28102811
28112812/**
@@ -2888,36 +2889,35 @@ static int scsi_internal_device_unblock(struct scsi_device *sdev,
28882889 return ret ;
28892890}
28902891
2891- static void
2892- device_block (struct scsi_device * sdev , void * data )
2893- {
2894- int ret ;
2895-
2896- ret = scsi_internal_device_block (sdev );
2897-
2898- WARN_ONCE (ret , "scsi_internal_device_block(%s) failed: ret = %d\n" ,
2899- dev_name (& sdev -> sdev_gendev ), ret );
2900- }
2901-
29022892static int
29032893target_block (struct device * dev , void * data )
29042894{
29052895 if (scsi_is_target_device (dev ))
29062896 starget_for_each_device (to_scsi_target (dev ), NULL ,
2907- device_block );
2897+ scsi_device_block );
29082898 return 0 ;
29092899}
29102900
2901+ /**
2902+ * scsi_block_targets - transition all SCSI child devices to SDEV_BLOCK state
2903+ * @dev: a parent device of one or more scsi_target devices
2904+ * @shost: the Scsi_Host to which this device belongs
2905+ *
2906+ * Iterate over all children of @dev, which should be scsi_target devices,
2907+ * and switch all subordinate scsi devices to SDEV_BLOCK state. Wait for
2908+ * ongoing scsi_queue_rq() calls to finish. May sleep.
2909+ *
2910+ * Note:
2911+ * @dev must not itself be a scsi_target device.
2912+ */
29112913void
2912- scsi_target_block ( struct device * dev )
2914+ scsi_block_targets ( struct Scsi_Host * shost , struct device * dev )
29132915{
2914- if (scsi_is_target_device (dev ))
2915- starget_for_each_device (to_scsi_target (dev ), NULL ,
2916- device_block );
2917- else
2918- device_for_each_child (dev , NULL , target_block );
2916+ WARN_ON_ONCE (scsi_is_target_device (dev ));
2917+ device_for_each_child (dev , NULL , target_block );
2918+ blk_mq_wait_quiesce_done (& shost -> tag_set );
29192919}
2920- EXPORT_SYMBOL_GPL (scsi_target_block );
2920+ EXPORT_SYMBOL_GPL (scsi_block_targets );
29212921
29222922static void
29232923device_unblock (struct scsi_device * sdev , void * data )
0 commit comments