Commit cc78d30a authored by Eric Moore's avatar Eric Moore Committed by James Bottomley

[SCSI] mpt fusion: fix for mounted raid volume filesytem that goes read-only

If there is IO going to the volume while a hidden disk is being torn down,
there is a case where we would return a DID_NO_CONNECT for IO sent to the
volume. The end result is the volume goes read-only. This problem is due to the
fact the firmware mapped target ids saved in per device object is phys_disk_num
for hidden  raid components, and target_id for the volume. There is a single
case when both phys_disk_num and target_id are equal, so enters this issue. We
fix this issue by checking the tflags when the device is torned down,
insuring the IO being completed is meant for hidden raid component, not the
volume.  In addition to this fix, there are a couple other cases to address
hidden raid components. For instance task_abort and device reset are not
supported by mpt fw for hidden raid components, a bus reset would be required
or target reset to volume.
Signed-off-by: default avatarEric Moore <Eric.Moore@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 958d4a32
...@@ -447,7 +447,12 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, ...@@ -447,7 +447,12 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SEPRequest_t *SEPMsg; SEPRequest_t *SEPMsg;
if (ioc->bus_type == FC) if (ioc->bus_type != SAS)
return;
/* Not supported for hidden raid components
*/
if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
return; return;
if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
...@@ -991,14 +996,19 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) ...@@ -991,14 +996,19 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
if (mf == NULL) if (mf == NULL)
continue; continue;
/* If the device is a hidden raid component, then its
* expected that the mf->function will be RAID_SCSI_IO
*/
if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
continue;
int_to_scsilun(vdevice->lun, &lun); int_to_scsilun(vdevice->lun, &lun);
if ((mf->Bus != vdevice->vtarget->channel) || if ((mf->Bus != vdevice->vtarget->channel) ||
(mf->TargetID != vdevice->vtarget->id) || (mf->TargetID != vdevice->vtarget->id) ||
memcmp(lun.scsi_lun, mf->LUN, 8)) memcmp(lun.scsi_lun, mf->LUN, 8))
continue; continue;
dsprintk(( "search_running: found (sc=%p, mf = %p) "
"channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
mf, mf->Bus, mf->TargetID, vdevice->lun));
/* Cleanup /* Cleanup
*/ */
...@@ -1008,9 +1018,11 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) ...@@ -1008,9 +1018,11 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
if ((unsigned char *)mf != sc->host_scribble) if ((unsigned char *)mf != sc->host_scribble)
continue; continue;
scsi_dma_unmap(sc); scsi_dma_unmap(sc);
sc->host_scribble = NULL; sc->host_scribble = NULL;
sc->result = DID_NO_CONNECT << 16; sc->result = DID_NO_CONNECT << 16;
dsprintk(( "search_running: found (sc=%p, mf = %p) "
"channel %d id %d, lun %d \n", sc, mf,
vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun));
sc->scsi_done(sc); sc->scsi_done(sc);
} }
} }
...@@ -1756,6 +1768,16 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1756,6 +1768,16 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
goto out; goto out;
} }
/* Task aborts are not supported for hidden raid components.
*/
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
dtmprintk((MYIOC_s_DEBUG_FMT "task abort: hidden raid "
"component (sc=%p)\n", ioc->name, SCpnt));
SCpnt->result = DID_RESET << 16;
retval = FAILED;
goto out;
}
/* Find this command /* Find this command
*/ */
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
...@@ -1849,6 +1871,13 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -1849,6 +1871,13 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
goto out; goto out;
} }
/* Target reset to hidden raid component is not supported
*/
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
retval = FAILED;
goto out;
}
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0, vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
mptscsih_get_tm_timeout(ioc)); mptscsih_get_tm_timeout(ioc));
...@@ -3131,6 +3160,16 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) ...@@ -3131,6 +3160,16 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
{ {
INTERNAL_CMD iocmd; INTERNAL_CMD iocmd;
/* Ignore hidden raid components, this is handled when the command
* is sent to the volume
*/
if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
return;
if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
!vdevice->configured_lun)
return;
/* Following parameters will not change /* Following parameters will not change
* in this routine. * in this routine.
*/ */
...@@ -3145,9 +3184,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) ...@@ -3145,9 +3184,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
iocmd.id = vdevice->vtarget->id; iocmd.id = vdevice->vtarget->id;
iocmd.lun = vdevice->lun; iocmd.lun = vdevice->lun;
if ((vdevice->vtarget->type == TYPE_DISK) && mptscsih_do_cmd(hd, &iocmd);
(vdevice->configured_lun))
mptscsih_do_cmd(hd, &iocmd);
} }
EXPORT_SYMBOL(mptscsih_remove); EXPORT_SYMBOL(mptscsih_remove);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment