scsi: visorhba: sanitze private device data allocation

There's no need to keep the private data for a device in a separate
list; better to store it in ->hostdata and do away with the additional
list.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Hannes Reinecke 2017-08-25 13:57:20 +02:00 коммит произвёл Martin K. Petersen
Родитель 6d415342ad
Коммит 7bc4e528d9
1 изменённых файлов: 53 добавлений и 70 удалений

Просмотреть файл

@ -47,8 +47,8 @@ MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR);
struct visordisk_info {
struct scsi_device *sdev;
u32 valid;
u32 channel, id, lun; /* Disk Path */
atomic_t ios_threshold;
atomic_t error_count;
struct visordisk_info *next;
@ -101,12 +101,6 @@ struct visorhba_devices_open {
struct visorhba_devdata *devdata;
};
#define for_each_vdisk_match(iter, list, match) \
for (iter = &list->head; iter->next; iter = iter->next) \
if ((iter->channel == match->channel) && \
(iter->id == match->id) && \
(iter->lun == match->lun))
/*
* visor_thread_start - starts a thread for the device
* @threadfn: Function the thread starts
@ -296,10 +290,9 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
* Returns whether the command was queued successfully or not.
*/
static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
struct scsi_cmnd *scsicmd)
struct scsi_device *scsidev)
{
struct uiscmdrsp *cmdrsp;
struct scsi_device *scsidev = scsicmd->device;
struct visorhba_devdata *devdata =
(struct visorhba_devdata *)scsidev->host->hostdata;
int notifyresult = 0xffff;
@ -347,12 +340,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
dev_dbg(&scsidev->sdev_gendev,
"visorhba: taskmgmt type=%d success; result=0x%x\n",
tasktype, notifyresult);
if (tasktype == TASK_MGMT_ABORT_TASK)
scsicmd->result = DID_ABORT << 16;
else
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp);
return SUCCESS;
@ -376,17 +363,20 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_ABORT_TASK */
struct scsi_device *scsidev;
struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
int rtn;
scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count);
else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count);
else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_ABORT << 16;
scsicmd->scsi_done(scsicmd);
}
return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd);
return rtn;
}
/*
@ -400,17 +390,20 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_LUN_RESET */
struct scsi_device *scsidev;
struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
int rtn;
scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count);
else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count);
else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
}
return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd);
return rtn;
}
/*
@ -424,17 +417,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
{
struct scsi_device *scsidev;
struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
int rtn;
scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
shost_for_each_device(scsidev, scsidev->host) {
vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count);
else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
}
return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd);
rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
}
return rtn;
}
/*
@ -569,25 +567,22 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev)
* LLD can alloc any struct & do init if needed.
*/
struct visordisk_info *vdisk;
struct visordisk_info *tmpvdisk;
struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
if (scsidev->hostdata)
return 0; /* already allocated return success */
devdata = (struct visorhba_devdata *)scsihost->hostdata;
if (!devdata)
return 0; /* even though we errored, treat as success */
for_each_vdisk_match(vdisk, devdata, scsidev)
return 0; /* already allocated return success */
tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
if (!tmpvdisk)
vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC);
if (!vdisk)
return -ENOMEM;
tmpvdisk->channel = scsidev->channel;
tmpvdisk->id = scsidev->id;
tmpvdisk->lun = scsidev->lun;
vdisk->next = tmpvdisk;
vdisk->sdev = scsidev;
scsidev->hostdata = vdisk;
return 0;
}
@ -603,17 +598,11 @@ static void visorhba_slave_destroy(struct scsi_device *scsidev)
/* midlevel calls this after device has been quiesced and
* before it is to be deleted.
*/
struct visordisk_info *vdisk, *delvdisk;
struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
struct visordisk_info *vdisk;
devdata = (struct visorhba_devdata *)scsihost->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
delvdisk = vdisk->next;
vdisk->next = delvdisk->next;
kfree(delvdisk);
return;
}
vdisk = scsidev->hostdata;
scsidev->hostdata = NULL;
kfree(vdisk);
}
static struct scsi_host_template visorhba_driver_template = {
@ -787,7 +776,6 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata)
static void
do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
{
struct visorhba_devdata *devdata;
struct visordisk_info *vdisk;
struct scsi_device *scsidev;
@ -800,12 +788,10 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
(cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
return;
/* Okay see what our error_count is here.... */
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
atomic_inc(&vdisk->error_count);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
}
vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
atomic_inc(&vdisk->error_count);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
}
}
@ -846,7 +832,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
char *this_page_orig;
int bufind = 0;
struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
scsidev = scsicmd->device;
if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
@ -883,13 +868,11 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
}
kfree(buf);
} else {
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->ios_threshold) > 0) {
atomic_dec(&vdisk->ios_threshold);
if (atomic_read(&vdisk->ios_threshold) == 0)
atomic_set(&vdisk->error_count, 0);
}
vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->ios_threshold) > 0) {
atomic_dec(&vdisk->ios_threshold);
if (atomic_read(&vdisk->ios_threshold) == 0)
atomic_set(&vdisk->error_count, 0);
}
}
}