From b574dd8dd180527a8edaa81de6bc606c5f0fb7b0 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Fri, 29 Aug 2008 04:39:46 +0000 Subject: [PATCH] Fix a locking mistake in daopen(). If the open fails, which can happen because the media was removed, the periph would get its refcount dropped and ultimately freed before getting unlocked. This created a dangling pointer that was easy to trip over. This fixes a common source of crashes with removaable media, but problems remain and will get tracked down. --- sys/cam/scsi/scsi_da.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 3831091e292..f63a9b0b914 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -674,18 +674,19 @@ daopen(struct disk *dp) softc->disk->d_fwheads = softc->params.heads; softc->disk->d_devstat->block_size = softc->params.secsize; softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE; - } - - if (error == 0) { + if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && (softc->quirks & DA_Q_NO_PREVENT) == 0) daprevent(periph, PR_PREVENT); - } else { + } else softc->flags &= ~DA_FLAG_OPEN; - cam_periph_release(periph); - } + cam_periph_unhold(periph); cam_periph_unlock(periph); + + if (error != 0) { + cam_periph_release(periph); + } return (error); }