summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>1999-06-24 08:55:02 +0000
committergrog <grog@FreeBSD.org>1999-06-24 08:55:02 +0000
commit427805d961eb460d4c56e65130d8bd1338c299d0 (patch)
treee649c390e7d023da1287e193b5e4d6308fa3556b
parent49d2ee55e519f1ee1d324ac9aa287900828449b8 (diff)
downloadFreeBSD-src-427805d961eb460d4c56e65130d8bd1338c299d0.zip
FreeBSD-src-427805d961eb460d4c56e65130d8bd1338c299d0.tar.gz
Split close_drive into two parts to ensure correct locking against the
daemon before closing a drive.
-rw-r--r--sys/dev/vinum/vinumio.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/sys/dev/vinum/vinumio.c b/sys/dev/vinum/vinumio.c
index 0fc51c5..720affb 100644
--- a/sys/dev/vinum/vinumio.c
+++ b/sys/dev/vinum/vinumio.c
@@ -189,35 +189,44 @@ init_drive(struct drive *drive, int verbose)
return set_drive_parms(drive); /* set various odds and ends */
}
-/* Close a drive if it's open. No errors */
+/* Close a drive if it's open. */
void
close_drive(struct drive *drive)
{
if (drive->vp) {
LOCKDRIVE(drive); /* keep the daemon out */
+ close_locked_drive(drive); /* and close it */
+ unlockdrive(drive);
+ }
+}
- /*
- * If we can't access the drive, we can't flush
- * the queues, which spec_close() will try to
- * do. Get rid of them here first
- */
- if (drive->state < drive_up) { /* we can't access the drive, */
- vn_lock(drive->vp, LK_EXCLUSIVE | LK_RETRY, drive->p);
- vinvalbuf(drive->vp, 0, NOCRED, drive->p, 0, 0);
- VOP_UNLOCK(drive->vp, 0, drive->p);
- }
- vn_close(drive->vp, FREAD | FWRITE, NOCRED, drive->p);
+/*
+ * Real drive close code, called with drive already locked. We have
+ * also checked that the drive is open. No errors.
+ */
+void
+close_locked_drive(struct drive *drive)
+{
+ /*
+ * If we can't access the drive, we can't flush
+ * the queues, which spec_close() will try to
+ * do. Get rid of them here first.
+ */
+ if (drive->state < drive_up) { /* we can't access the drive, */
+ vn_lock(drive->vp, LK_EXCLUSIVE | LK_RETRY, drive->p);
+ vinvalbuf(drive->vp, 0, NOCRED, drive->p, 0, 0);
+ VOP_UNLOCK(drive->vp, 0, drive->p);
+ }
+ vn_close(drive->vp, FREAD | FWRITE, NOCRED, drive->p);
#ifdef VINUMDEBUG
- if ((debug & DEBUG_WARNINGS) /* want to hear about them */
- &&(drive->vp->v_usecount)) /* XXX shouldn't happen */
- log(LOG_WARNING,
- "close_drive %s: use count still %d\n",
- drive->devicename,
- drive->vp->v_usecount);
+ if ((debug & DEBUG_WARNINGS) /* want to hear about them */
+ &&(drive->vp->v_usecount)) /* XXX shouldn't happen */
+ log(LOG_WARNING,
+ "close_drive %s: use count still %d\n",
+ drive->devicename,
+ drive->vp->v_usecount);
#endif
- drive->vp = NULL;
- unlockdrive(drive);
- }
+ drive->vp = NULL;
}
/*
OpenPOWER on IntegriCloud