[SCSI] mpt2sas: Fix for Panic when inactive volume is tried deleting
The driver was setting the action to MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, which only returns active volumes. In order to get info on inactive volumes, the driver needs to change the action to MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM, and traverse each config till the iocstatus is MPI2_IOCSTATUS_CONFIG_INVALID_PAGE returned. Added a change in the driver to remove the instance of sas_device object when the driver returns "1" from the slave_configure callback. Also fixed code to report the hot spares to the operating system with a /dev/sg assigned. Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Cc: stable@kernel.org Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Este cometimento está contido em:

cometido por
James Bottomley

ascendente
6faace2a0e
cometimento
35116db95c
@@ -1356,6 +1356,9 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
int r, i, config_page_sz;
|
||||
u16 ioc_status;
|
||||
int config_num;
|
||||
u16 element_type;
|
||||
u16 phys_disk_dev_handle;
|
||||
|
||||
*volume_handle = 0;
|
||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
||||
@@ -1371,35 +1374,53 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
mpi_request.PageAddress =
|
||||
cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
|
||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
|
||||
config_page = kmalloc(config_page_sz, GFP_KERNEL);
|
||||
if (!config_page)
|
||||
if (!config_page) {
|
||||
r = -1;
|
||||
goto out;
|
||||
r = _config_request(ioc, &mpi_request, &mpi_reply,
|
||||
MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
||||
config_page_sz);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = -1;
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
|
||||
goto out;
|
||||
for (i = 0; i < config_page->NumElements; i++) {
|
||||
if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) &
|
||||
MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
|
||||
MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
|
||||
continue;
|
||||
if (le16_to_cpu(config_page->ConfigElement[i].
|
||||
PhysDiskDevHandle) == pd_handle) {
|
||||
*volume_handle = le16_to_cpu(config_page->
|
||||
ConfigElement[i].VolDevHandle);
|
||||
r = 0;
|
||||
}
|
||||
config_num = 0xff;
|
||||
while (1) {
|
||||
mpi_request.PageAddress = cpu_to_le32(config_num +
|
||||
MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
|
||||
r = _config_request(ioc, &mpi_request, &mpi_reply,
|
||||
MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
||||
config_page_sz);
|
||||
if (r)
|
||||
goto out;
|
||||
r = -1;
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
||||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
|
||||
goto out;
|
||||
for (i = 0; i < config_page->NumElements; i++) {
|
||||
element_type = le16_to_cpu(config_page->
|
||||
ConfigElement[i].ElementFlags) &
|
||||
MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
|
||||
if (element_type ==
|
||||
MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
|
||||
element_type ==
|
||||
MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
|
||||
phys_disk_dev_handle =
|
||||
le16_to_cpu(config_page->ConfigElement[i].
|
||||
PhysDiskDevHandle);
|
||||
if (phys_disk_dev_handle == pd_handle) {
|
||||
*volume_handle =
|
||||
le16_to_cpu(config_page->
|
||||
ConfigElement[i].VolDevHandle);
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
} else if (element_type ==
|
||||
MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
|
||||
*volume_handle = 0;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
config_num = config_page->ConfigNum;
|
||||
}
|
||||
out:
|
||||
kfree(config_page);
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador