diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2021-04-14 20:08:01 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2021-04-16 05:19:39 +0300 |
commit | ab1fa88062f8d1d9e8947719b8ed3ab48a60476c (patch) | |
tree | 745362fcf510bd034366df38e3b080ddc6f3a96e /drivers/s390 | |
parent | 8824db894dd1da48bad363612577ef410a5d1828 (diff) | |
download | linux-ab1fa88062f8d1d9e8947719b8ed3ab48a60476c.tar.xz |
scsi: zfcp: Fix sysfs roll-back on error in zfcp_adapter_enqueue()
When zfcp_adapter_enqueue() fails to create the zfcp_sysfs_adapter_attrs
group, it calls zfcp_adapter_unregister() to tear down the adapter state
again. This then unconditionally attempts to remove the
zfcp_sysfs_adapter_attrs group, resulting in a "group not found" WARN from
sysfs code.
Avoid this by copying most of zfcp_adapter_unregister() into the error
path, allowing for more fine-granular roll-back. Then skip the sysfs
tear-down steps if we haven't progressed this far in the initialization.
Link: https://lore.kernel.org/r/790922cc3af075795fff9a4b787e6bda19bdb3be.1618417667.git.bblock@linux.ibm.com
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 768873dd55b8..abad77694e72 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -418,7 +418,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) goto failed; if (zfcp_diag_sysfs_setup(adapter)) - goto failed; + goto err_diag_sysfs; /* report size limit per scatter-gather segment */ adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; @@ -427,8 +427,24 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) return adapter; +err_diag_sysfs: + sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs); failed: - zfcp_adapter_unregister(adapter); + /* TODO: make this more fine-granular */ + cancel_delayed_work_sync(&adapter->scan_work); + cancel_work_sync(&adapter->stat_work); + cancel_work_sync(&adapter->ns_up_work); + cancel_work_sync(&adapter->version_change_lost_work); + zfcp_destroy_adapter_work_queue(adapter); + + zfcp_fc_wka_ports_force_offline(adapter->gs); + zfcp_scsi_adapter_unregister(adapter); + + zfcp_erp_thread_kill(adapter); + zfcp_dbf_adapter_unregister(adapter); + zfcp_qdio_destroy(adapter->qdio); + + zfcp_ccw_adapter_put(adapter); /* final put to release */ return ERR_PTR(-ENOMEM); } |