Skip to content

Commit 362432e

Browse files
Chaohai Chenmartinkpetersen
authored andcommitted
scsi: libsas: Add rollback handling when an error occurs
In sas_register_phys(), if an error is triggered in the loop process, we need to roll back the resources that have already been requested. Add sas_unregister_phys() when an error occurs in sas_register_ha(). [mkp: a few coding style tweaks and address John's comment] Signed-off-by: Chaohai Chen <wdhh6@aliyun.com> Reviewed-by: John Garry <john.g.garry@oracle.com> Link: https://patch.msgid.link/20251206060616.69216-1-wdhh6@aliyun.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent fd81bc5 commit 362432e

3 files changed

Lines changed: 32 additions & 3 deletions

File tree

drivers/scsi/libsas/sas_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
141141
Undo_ports:
142142
sas_unregister_ports(sas_ha);
143143
Undo_phys:
144+
sas_unregister_phys(sas_ha);
144145

145146
return error;
146147
}

drivers/scsi/libsas/sas_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev);
5454
void sas_scsi_recover_host(struct Scsi_Host *shost);
5555

5656
int sas_register_phys(struct sas_ha_struct *sas_ha);
57+
void sas_unregister_phys(struct sas_ha_struct *sas_ha);
5758

5859
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags);
5960
void sas_free_event(struct asd_sas_event *event);

drivers/scsi/libsas/sas_phy.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static void sas_phye_shutdown(struct work_struct *work)
116116
int sas_register_phys(struct sas_ha_struct *sas_ha)
117117
{
118118
int i;
119+
int err;
119120

120121
/* Now register the phys. */
121122
for (i = 0; i < sas_ha->num_phys; i++) {
@@ -132,8 +133,10 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
132133
phy->frame_rcvd_size = 0;
133134

134135
phy->phy = sas_phy_alloc(&sas_ha->shost->shost_gendev, i);
135-
if (!phy->phy)
136-
return -ENOMEM;
136+
if (!phy->phy) {
137+
err = -ENOMEM;
138+
goto rollback;
139+
}
137140

138141
phy->phy->identify.initiator_port_protocols =
139142
phy->iproto;
@@ -146,10 +149,34 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
146149
phy->phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN;
147150
phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
148151

149-
sas_phy_add(phy->phy);
152+
err = sas_phy_add(phy->phy);
153+
if (err) {
154+
sas_phy_free(phy->phy);
155+
goto rollback;
156+
}
150157
}
151158

152159
return 0;
160+
rollback:
161+
for (i-- ; i >= 0 ; i--) {
162+
struct asd_sas_phy *phy = sas_ha->sas_phy[i];
163+
164+
sas_phy_delete(phy->phy);
165+
sas_phy_free(phy->phy);
166+
}
167+
return err;
168+
}
169+
170+
void sas_unregister_phys(struct sas_ha_struct *sas_ha)
171+
{
172+
int i;
173+
174+
for (i = 0 ; i < sas_ha->num_phys ; i++) {
175+
struct asd_sas_phy *phy = sas_ha->sas_phy[i];
176+
177+
sas_phy_delete(phy->phy);
178+
sas_phy_free(phy->phy);
179+
}
153180
}
154181

155182
const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = {

0 commit comments

Comments
 (0)