summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2015-08-20 23:08:33 +0000
committermlelstv <mlelstv@NetBSD.org>2015-08-20 23:08:33 +0000
commit915656a2d2a3428fd1bd9680972c1e26be55ac99 (patch)
tree19ab558c3c2f8fbc357979781cc1da385f115a45 /sys/dev
parentcb0bd186595aebd31f975d2c9a63935b8e93fcd1 (diff)
when scanning for disklabels, close block device only when this was
the first open. The device driver doesn't do reference counting. This is still subject to race conditions.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/dkwedge/dk.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/dev/dkwedge/dk.c b/sys/dev/dkwedge/dk.c
index 80adc4ea5c2..61085ea7182 100644
--- a/sys/dev/dkwedge/dk.c
+++ b/sys/dev/dkwedge/dk.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dk.c,v 1.79 2015/01/02 01:14:22 christos Exp $ */
+/* $NetBSD: dk.c,v 1.80 2015/08/20 23:08:33 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.79 2015/01/02 01:14:22 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.80 2015/08/20 23:08:33 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_dkwedge.h"
@@ -944,7 +944,7 @@ dkwedge_read(struct disk *pdk, struct vnode *vp, daddr_t blkno,
void *tbuf, size_t len)
{
buf_t *bp;
- int error;
+ int error, isopen;
/*
* The kernel cannot read from a character device vnode
@@ -964,6 +964,12 @@ dkwedge_read(struct disk *pdk, struct vnode *vp, daddr_t blkno,
bp->b_cylinder = 0;
bp->b_error = 0;
+ /*
+ * XXX Only the last user of a block device can close it.
+ * There is no reference counting in the driver.
+ */
+ isopen = pdk->dk_bopenmask & (1 << DISKPART(bp->b_dev));
+
error = bdev_open(bp->b_dev, FREAD, S_IFBLK, curlwp);
if (error)
return error;
@@ -972,7 +978,8 @@ dkwedge_read(struct disk *pdk, struct vnode *vp, daddr_t blkno,
error = biowait(bp);
putiobuf(bp);
- bdev_close(bp->b_dev, FREAD, S_IFBLK, curlwp);
+ if (!isopen)
+ bdev_close(bp->b_dev, FREAD, S_IFBLK, curlwp);
return error;
}