scsi: Protect SCSI device state changes with a mutex
Serializing SCSI device state changes avoids that two state changes can occur concurrently, e.g. the state changes in scsi_target_block() and __scsi_remove_device(). This serialization is essential to make patch "Make __scsi_remove_device go straight from BLOCKED to DEL" work reliably. Enable this mechanism for all scsi_target_*block() callers but not for the scsi_internal_device_unblock() calls from the mpt3sas driver because that driver can call scsi_internal_device_unblock() from atomic context. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:

committed by
Martin K. Petersen

parent
43f7571be0
commit
0db6ca8a5e
@@ -1818,8 +1818,9 @@ static void sd_eh_reset(struct scsi_cmnd *scmd)
|
||||
static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
|
||||
{
|
||||
struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
|
||||
struct scsi_device *sdev = scmd->device;
|
||||
|
||||
if (!scsi_device_online(scmd->device) ||
|
||||
if (!scsi_device_online(sdev) ||
|
||||
!scsi_medium_access_command(scmd) ||
|
||||
host_byte(scmd->result) != DID_TIME_OUT ||
|
||||
eh_disp != SUCCESS)
|
||||
@@ -1845,7 +1846,9 @@ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
|
||||
if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
|
||||
scmd_printk(KERN_ERR, scmd,
|
||||
"Medium access timeout failure. Offlining disk!\n");
|
||||
scsi_device_set_state(scmd->device, SDEV_OFFLINE);
|
||||
mutex_lock(&sdev->state_mutex);
|
||||
scsi_device_set_state(sdev, SDEV_OFFLINE);
|
||||
mutex_unlock(&sdev->state_mutex);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user