Fix several cases where the periph lock was held over malloc.

Submitted by:	Jaakko Heinonen
This commit is contained in:
Scott Long 2009-12-02 16:08:33 +00:00
parent 8b8ec2e2b1
commit 645275a641
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=200036

View File

@ -2673,12 +2673,10 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
authinfo = (struct dvd_authinfo *)addr;
cam_periph_lock(periph);
if (cmd == DVDIOCREPORTKEY)
error = cdreportkey(periph, authinfo);
else
error = cdsendkey(periph, authinfo);
cam_periph_unlock(periph);
break;
}
case DVDIOCREADSTRUCTURE: {
@ -2686,9 +2684,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
dvdstruct = (struct dvd_struct *)addr;
cam_periph_lock(periph);
error = cdreaddvdstructure(periph, dvdstruct);
cam_periph_unlock(periph);
break;
}
@ -3732,8 +3728,6 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
databuf = NULL;
lba = 0;
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
switch (authinfo->format) {
case DVD_REPORT_AGID:
length = sizeof(struct scsi_report_key_data_agid);
@ -3759,9 +3753,7 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
length = 0;
break;
default:
error = EINVAL;
goto bailout;
break; /* NOTREACHED */
return (EINVAL);
}
if (length != 0) {
@ -3769,6 +3761,8 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
} else
databuf = NULL;
cam_periph_lock(periph);
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
scsi_report_key(&ccb->csio,
/* retries */ 1,
@ -3869,12 +3863,14 @@ cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
goto bailout;
break; /* NOTREACHED */
}
bailout:
xpt_release_ccb(ccb);
cam_periph_unlock(periph);
if (databuf != NULL)
free(databuf, M_DEVBUF);
xpt_release_ccb(ccb);
return(error);
}
@ -3889,8 +3885,6 @@ cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
error = 0;
databuf = NULL;
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
switch(authinfo->format) {
case DVD_SEND_CHALLENGE: {
struct scsi_report_key_data_challenge *challenge_data;
@ -3942,11 +3936,12 @@ cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
break;
}
default:
error = EINVAL;
goto bailout;
break; /* NOTREACHED */
return (EINVAL);
}
cam_periph_lock(periph);
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
scsi_send_key(&ccb->csio,
/* retries */ 1,
/* cbfcnp */ cddone,
@ -3961,13 +3956,12 @@ cdsendkey(struct cam_periph *periph, struct dvd_authinfo *authinfo)
error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
/*sense_flags*/SF_RETRY_UA);
bailout:
xpt_release_ccb(ccb);
cam_periph_unlock(periph);
if (databuf != NULL)
free(databuf, M_DEVBUF);
xpt_release_ccb(ccb);
return(error);
}
@ -3985,8 +3979,6 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
/* The address is reserved for many of the formats */
address = 0;
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
switch(dvdstruct->format) {
case DVD_STRUCT_PHYSICAL:
length = sizeof(struct scsi_read_dvd_struct_data_physical);
@ -4004,13 +3996,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
length = sizeof(struct scsi_read_dvd_struct_data_manufacturer);
break;
case DVD_STRUCT_CMI:
error = ENODEV;
goto bailout;
#ifdef notyet
length = sizeof(struct scsi_read_dvd_struct_data_copy_manage);
address = dvdstruct->address;
#endif
break; /* NOTREACHED */
return (ENODEV);
case DVD_STRUCT_PROTDISCID:
length = sizeof(struct scsi_read_dvd_struct_data_prot_discid);
break;
@ -4027,21 +4013,9 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
length = sizeof(struct scsi_read_dvd_struct_data_spare_area);
break;
case DVD_STRUCT_RMD_LAST:
error = ENODEV;
goto bailout;
#ifdef notyet
length = sizeof(struct scsi_read_dvd_struct_data_rmd_borderout);
address = dvdstruct->address;
#endif
break; /* NOTREACHED */
return (ENODEV);
case DVD_STRUCT_RMD_RMA:
error = ENODEV;
goto bailout;
#ifdef notyet
length = sizeof(struct scsi_read_dvd_struct_data_rmd);
address = dvdstruct->address;
#endif
break; /* NOTREACHED */
return (ENODEV);
case DVD_STRUCT_PRERECORDED:
length = sizeof(struct scsi_read_dvd_struct_data_leadin);
break;
@ -4049,13 +4023,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
length = sizeof(struct scsi_read_dvd_struct_data_disc_id);
break;
case DVD_STRUCT_DCB:
error = ENODEV;
goto bailout;
#ifdef notyet
length = sizeof(struct scsi_read_dvd_struct_data_dcb);
address = dvdstruct->address;
#endif
break; /* NOTREACHED */
return (ENODEV);
case DVD_STRUCT_LIST:
/*
* This is the maximum allocation length for the READ DVD
@ -4067,9 +4035,7 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
length = 65535;
break;
default:
error = EINVAL;
goto bailout;
break; /* NOTREACHED */
return (EINVAL);
}
if (length != 0) {
@ -4077,6 +4043,9 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
} else
databuf = NULL;
cam_periph_lock(periph);
ccb = cdgetccb(periph, CAM_PRIORITY_NORMAL);
scsi_read_dvd_structure(&ccb->csio,
/* retries */ 1,
/* cbfcnp */ cddone,
@ -4164,13 +4133,14 @@ cdreaddvdstructure(struct cam_periph *periph, struct dvd_struct *dvdstruct)
min(sizeof(dvdstruct->data), dvdstruct->length));
break;
}
bailout:
xpt_release_ccb(ccb);
cam_periph_unlock(periph);
if (databuf != NULL)
free(databuf, M_DEVBUF);
xpt_release_ccb(ccb);
return(error);
}