mps(4), mpr(4): Fix lifetime of command buffer for mp?sas_get_sata_identify
In the event that the ID command timed out, mps(4)/mpr(4) did not free the command until it could be cancelled. However, it freed the associated buffer (cm_data). Fix the lifetime issue by freeing the associated buffer only after Abort Task or controller reset. Reviewed by: scottl Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D18612
This commit is contained in:
parent
8ec22c4d65
commit
8277ce2b78
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=342354
@ -1169,6 +1169,12 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
|
||||
cm->cm_reply = NULL;
|
||||
completed = 0;
|
||||
|
||||
if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
|
||||
MPASS(cm->cm_data);
|
||||
free(cm->cm_data, M_MPR);
|
||||
cm->cm_data = NULL;
|
||||
}
|
||||
|
||||
if (cm->cm_flags & MPR_CM_FLAGS_POLLED)
|
||||
cm->cm_flags |= MPR_CM_FLAGS_COMPLETE;
|
||||
|
||||
|
@ -1026,6 +1026,7 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
|
||||
for (i = 1; i < sc->num_reqs; i++) {
|
||||
cm = &sc->commands[i];
|
||||
if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
|
||||
free(cm->cm_data, M_MPR);
|
||||
mpr_free_command(sc, cm);
|
||||
}
|
||||
}
|
||||
@ -1208,15 +1209,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
|
||||
out:
|
||||
/*
|
||||
* If the SATA_ID_TIMEOUT flag has been set for this command, don't free
|
||||
* it. The command will be freed after sending a target reset TM. If
|
||||
* the command did timeout, use EWOULDBLOCK.
|
||||
* it. The command and buffer will be freed after sending an Abort
|
||||
* Task TM. If the command did timeout, use EWOULDBLOCK.
|
||||
*/
|
||||
if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
|
||||
if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
|
||||
mpr_free_command(sc, cm);
|
||||
else if (error == 0)
|
||||
free(buffer, M_MPR);
|
||||
} else if (error == 0)
|
||||
error = EWOULDBLOCK;
|
||||
cm->cm_data = NULL;
|
||||
free(buffer, M_MPR);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1108,6 +1108,12 @@ mpssas_complete_all_commands(struct mps_softc *sc)
|
||||
cm->cm_reply = NULL;
|
||||
completed = 0;
|
||||
|
||||
if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
|
||||
MPASS(cm->cm_data);
|
||||
free(cm->cm_data, M_MPT2);
|
||||
cm->cm_data = NULL;
|
||||
}
|
||||
|
||||
if (cm->cm_flags & MPS_CM_FLAGS_POLLED)
|
||||
cm->cm_flags |= MPS_CM_FLAGS_COMPLETE;
|
||||
|
||||
|
@ -818,6 +818,7 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
|
||||
for (i = 1; i < sc->num_reqs; i++) {
|
||||
cm = &sc->commands[i];
|
||||
if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
|
||||
free(cm->cm_data, M_MPT2);
|
||||
mps_free_command(sc, cm);
|
||||
}
|
||||
}
|
||||
@ -1000,15 +1001,15 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
|
||||
out:
|
||||
/*
|
||||
* If the SATA_ID_TIMEOUT flag has been set for this command, don't free
|
||||
* it. The command will be freed after sending a target reset TM. If
|
||||
* the command did timeout, use EWOULDBLOCK.
|
||||
* it. The command and buffer will be freed after sending an Abort
|
||||
* Task TM. If the command did timeout, use EWOULDBLOCK.
|
||||
*/
|
||||
if ((cm != NULL)
|
||||
&& (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
|
||||
&& (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
|
||||
mps_free_command(sc, cm);
|
||||
else if (error == 0)
|
||||
free(buffer, M_MPT2);
|
||||
} else if (error == 0)
|
||||
error = EWOULDBLOCK;
|
||||
free(buffer, M_MPT2);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user