Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/dkwedge No longer access the disk driver directly.
details: https://anonhg.NetBSD.org/src/rev/a11784801af2
branches: trunk
changeset: 810230:a11784801af2
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sat Aug 22 07:48:14 2015 +0000
description:
No longer access the disk driver directly.
If there is an open wedge, temporarily reference its vnode.
Otherwise try to open the block device.
diffstat:
sys/dev/dkwedge/dk.c | 114 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 83 insertions(+), 31 deletions(-)
diffs (182 lines):
diff -r c24243ba5744 -r a11784801af2 sys/dev/dkwedge/dk.c
--- a/sys/dev/dkwedge/dk.c Sat Aug 22 07:42:46 2015 +0000
+++ b/sys/dev/dkwedge/dk.c Sat Aug 22 07:48:14 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dk.c,v 1.81 2015/08/22 07:42:46 mlelstv Exp $ */
+/* $NetBSD: dk.c,v 1.82 2015/08/22 07:48:14 mlelstv Exp $ */
/*-
* Copyright (c) 2004, 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.81 2015/08/22 07:42:46 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.82 2015/08/22 07:48:14 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_dkwedge.h"
@@ -102,6 +102,8 @@
static int dkwedge_detach(device_t, int);
static void dkwedge_delall1(struct disk *, bool);
static int dkwedge_del1(struct dkwedge_info *, int);
+static struct vnode *dk_open_parent(dev_t, int);
+static int dk_close_parent(struct vnode *, int);
static dev_type_open(dkopen);
static dev_type_close(dkclose);
@@ -945,34 +947,58 @@
{
buf_t *bp;
int error;
+ bool isopen;
+ dev_t bdev;
+ struct vnode *bdevvp;
/*
* The kernel cannot read from a character device vnode
* as physio() only handles user memory.
*
- * Determine the corresponding block device and call into
- * the driver directly.
+ * If the block device has already been opened by a wedge
+ * use that vnode and temporarily bump the open counter.
+ *
+ * Otherwise try to open the block device.
*/
- bp = getiobuf(vp, true);
+ bdev = devsw_chr2blk(vp->v_rdev);
+
+ mutex_enter(&pdk->dk_rawlock);
+ if (pdk->dk_rawopens != 0) {
+ KASSERT(pdk->dk_rawvp != NULL);
+ isopen = true;
+ ++pdk->dk_rawopens;
+ bdevvp = pdk->dk_rawvp;
+ } else {
+ isopen = false;
+ bdevvp = dk_open_parent(bdev, FREAD);
+ }
+ mutex_exit(&pdk->dk_rawlock);
+
+ if (bdevvp == NULL)
+ return EBUSY;
+
+ bp = getiobuf(bdevvp, true);
bp->b_flags = B_READ;
bp->b_cflags = BC_BUSY;
- bp->b_dev = devsw_chr2blk(vp->v_rdev);
+ bp->b_dev = bdev;
bp->b_data = tbuf;
bp->b_bufsize = bp->b_bcount = len;
bp->b_blkno = blkno;
bp->b_cylinder = 0;
bp->b_error = 0;
- error = bdev_open(bp->b_dev, FREAD, S_IFBLK, curlwp);
- if (error)
- return error;
-
- bdev_strategy(bp);
+ VOP_STRATEGY(bdevvp, bp);
error = biowait(bp);
putiobuf(bp);
- bdev_close(bp->b_dev, FREAD, S_IFBLK, curlwp);
+ mutex_enter(&pdk->dk_rawlock);
+ if (isopen) {
+ --pdk->dk_rawopens;
+ } else {
+ dk_close_parent(bdevvp, FREAD);
+ }
+ mutex_exit(&pdk->dk_rawlock);
return error;
}
@@ -995,6 +1021,48 @@
return (dkwedges[unit]);
}
+static struct vnode *
+dk_open_parent(dev_t dev, int mode)
+{
+ struct vnode *vp;
+ int error;
+
+ error = bdevvp(dev, &vp);
+ if (error)
+ return NULL;
+
+ error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (error) {
+ vrele(vp);
+ return NULL;
+ }
+ error = VOP_OPEN(vp, mode, NOCRED);
+ if (error) {
+ vput(vp);
+ return NULL;
+ }
+
+ /* VOP_OPEN() doesn't do this for us. */
+ if (mode & FWRITE) {
+ mutex_enter(vp->v_interlock);
+ vp->v_writecount++;
+ mutex_exit(vp->v_interlock);
+ }
+
+ VOP_UNLOCK(vp);
+
+ return vp;
+}
+
+static int
+dk_close_parent(struct vnode *vp, int mode)
+{
+ int error;
+
+ error = vn_close(vp, mode, NOCRED);
+ return error;
+}
+
/*
* dkopen: [devsw entry point]
*
@@ -1023,24 +1091,9 @@
if (sc->sc_dk.dk_openmask == 0) {
if (sc->sc_parent->dk_rawopens == 0) {
KASSERT(sc->sc_parent->dk_rawvp == NULL);
- error = bdevvp(sc->sc_pdev, &vp);
- if (error)
- goto popen_fail;
- error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- if (error) {
- vrele(vp);
+ vp = dk_open_parent(sc->sc_pdev, FREAD | FWRITE);
+ if (vp == NULL)
goto popen_fail;
- }
- error = VOP_OPEN(vp, FREAD | FWRITE, NOCRED);
- if (error) {
- vput(vp);
- goto popen_fail;
- }
- /* VOP_OPEN() doesn't do this for us. */
- mutex_enter(vp->v_interlock);
- vp->v_writecount++;
- mutex_exit(vp->v_interlock);
- VOP_UNLOCK(vp);
sc->sc_parent->dk_rawvp = vp;
}
sc->sc_parent->dk_rawopens++;
@@ -1076,8 +1129,7 @@
if (doclose) {
KASSERT(sc->sc_parent->dk_rawvp != NULL);
- error = vn_close(sc->sc_parent->dk_rawvp,
- FREAD | FWRITE, NOCRED);
+ dk_close_parent(sc->sc_parent->dk_rawvp, FREAD | FWRITE);
sc->sc_parent->dk_rawvp = NULL;
}
Home |
Main Index |
Thread Index |
Old Index