diff options
| author | mlelstv <mlelstv@NetBSD.org> | 2015-08-20 23:08:33 +0000 |
|---|---|---|
| committer | mlelstv <mlelstv@NetBSD.org> | 2015-08-20 23:08:33 +0000 |
| commit | 915656a2d2a3428fd1bd9680972c1e26be55ac99 (patch) | |
| tree | 19ab558c3c2f8fbc357979781cc1da385f115a45 /sys/dev | |
| parent | cb0bd186595aebd31f975d2c9a63935b8e93fcd1 (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.c | 15 |
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; } |
