We need to hold the periph lock when we release the ccb (and when we

run it). Make sure that we do. Simplify the flow a bit, and fix a
comment since we do need to do these things.

Noticed by: cperciva (not sure why my invariants kernel didn't trigger)
This commit is contained in:
imp 2020-05-03 04:22:27 +00:00
parent 8aa4dbecf5
commit a80bf22f96

View File

@ -426,26 +426,26 @@ ndaioctl(struct disk *dp, u_long cmd, void *data, int fflag,
*/ */
memset(&mapinfo, 0, sizeof(mapinfo)); memset(&mapinfo, 0, sizeof(mapinfo));
error = cam_periph_mapmem(ccb, &mapinfo, maxmap); error = cam_periph_mapmem(ccb, &mapinfo, maxmap);
if (error) { if (error)
xpt_release_ccb(ccb); goto out;
return (error);
}
/* /*
* Lock the periph and run the command. XXX do we need * Lock the periph and run the command.
* to lock the periph?
*/ */
cam_periph_lock(periph); cam_periph_lock(periph);
cam_periph_runccb(ccb, NULL, CAM_RETRY_SELTO, SF_RETRY_UA | SF_NO_PRINT, cam_periph_runccb(ccb, NULL, CAM_RETRY_SELTO,
NULL); SF_RETRY_UA | SF_NO_PRINT, NULL);
cam_periph_unlock(periph);
/* /*
* Tear down mapping and return status. * Tear down mapping and return status.
*/ */
cam_periph_unlock(periph);
cam_periph_unmapmem(ccb, &mapinfo); cam_periph_unmapmem(ccb, &mapinfo);
error = (ccb->ccb_h.status == CAM_REQ_CMP) ? 0 : EIO; error = (ccb->ccb_h.status == CAM_REQ_CMP) ? 0 : EIO;
out:
cam_periph_lock(periph);
xpt_release_ccb(ccb); xpt_release_ccb(ccb);
cam_periph_unlock(periph);
return (error); return (error);
} }
default: default: