summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorchs <chs@NetBSD.org>2006-03-14 15:07:29 +0000
committerchs <chs@NetBSD.org>2006-03-14 15:07:29 +0000
commit3b7a4338dbbd62efff6bb06a0b44ed5b23d16a12 (patch)
tree5e62004783399695ac495b3776ab9fee3440f585 /sys/dev
parentae84301430031ce80776241591dc26de1479cd06 (diff)
use lockmgr() instead of bespoke code for mutual exclusion in fss_ioctl().
only take the lock when we actually need it (and particularly not for unknown cmds that are just going to fail immediately). fixes PR 33060.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fss.c29
-rw-r--r--sys/dev/fssvar.h4
2 files changed, 12 insertions, 21 deletions
diff --git a/sys/dev/fss.c b/sys/dev/fss.c
index d26992d17ad..cdc7a3e826f 100644
--- a/sys/dev/fss.c
+++ b/sys/dev/fss.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fss.c,v 1.22 2006/01/11 00:49:59 yamt Exp $ */
+/* $NetBSD: fss.c,v 1.23 2006/03/14 15:07:29 chs Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.22 2006/01/11 00:49:59 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.23 2006/03/14 15:07:29 chs Exp $");
#include "fss.h"
@@ -162,6 +162,7 @@ fssattach(int num)
sc->sc_unit = i;
sc->sc_bdev = NODEV;
simple_lock_init(&sc->sc_slock);
+ lockinit(&sc->sc_lock, PRIBIO, "fsslock", 0, 0);
bufq_alloc(&sc->sc_bufq, "fcfs", 0);
}
}
@@ -262,7 +263,7 @@ fss_write(dev_t dev, struct uio *uio, int flags)
int
fss_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l)
{
- int s, error;
+ int error;
struct fss_softc *sc;
struct fss_set *fss = (struct fss_set *)data;
struct fss_get *fsg = (struct fss_get *)data;
@@ -270,37 +271,31 @@ fss_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l)
if ((sc = FSS_DEV_TO_SOFTC(dev)) == NULL)
return ENODEV;
- FSS_LOCK(sc, s);
- while ((sc->sc_flags & FSS_EXCL) == FSS_EXCL) {
- error = ltsleep(sc, PRIBIO|PCATCH, "fsslock", 0, &sc->sc_slock);
- if (error) {
- FSS_UNLOCK(sc, s);
- return error;
- }
- }
- sc->sc_flags |= FSS_EXCL;
- FSS_UNLOCK(sc, s);
-
switch (cmd) {
case FSSIOCSET:
+ lockmgr(&sc->sc_lock, LK_EXCLUSIVE, NULL);
if ((flag & FWRITE) == 0)
error = EPERM;
else if ((sc->sc_flags & FSS_ACTIVE) != 0)
error = EBUSY;
else
error = fss_create_snapshot(sc, fss, l);
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
break;
case FSSIOCCLR:
+ lockmgr(&sc->sc_lock, LK_EXCLUSIVE, NULL);
if ((flag & FWRITE) == 0)
error = EPERM;
else if ((sc->sc_flags & FSS_ACTIVE) == 0)
error = ENXIO;
else
error = fss_delete_snapshot(sc, l);
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
break;
case FSSIOCGET:
+ lockmgr(&sc->sc_lock, LK_EXCLUSIVE, NULL);
switch (sc->sc_flags & (FSS_PERSISTENT | FSS_ACTIVE)) {
case FSS_ACTIVE:
memcpy(fsg->fsg_mount, sc->sc_mntname, MNAMELEN);
@@ -322,6 +317,7 @@ fss_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l)
error = ENXIO;
break;
}
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
break;
case FSSIOFSET:
@@ -339,11 +335,6 @@ fss_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l)
break;
}
- FSS_LOCK(sc, s);
- sc->sc_flags &= ~FSS_EXCL;
- FSS_UNLOCK(sc, s);
- wakeup(sc);
-
return error;
}
diff --git a/sys/dev/fssvar.h b/sys/dev/fssvar.h
index 87ead9e1f27..0a4fa8c21a1 100644
--- a/sys/dev/fssvar.h
+++ b/sys/dev/fssvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fssvar.h,v 1.12 2005/12/11 12:20:53 christos Exp $ */
+/* $NetBSD: fssvar.h,v 1.13 2006/03/14 15:07:29 chs Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -144,11 +144,11 @@ struct fss_cache {
struct fss_softc {
int sc_unit; /* Logical unit number */
struct simplelock sc_slock; /* Protect this softc */
+ struct lock sc_lock; /* Sleep lock for fss_ioctl */
volatile int sc_flags; /* Flags */
#define FSS_ACTIVE 0x01 /* Snapshot is active */
#define FSS_ERROR 0x02 /* I/O error occurred */
#define FSS_BS_THREAD 0x04 /* Kernel thread is running */
-#define FSS_EXCL 0x08 /* Exclusive access granted */
#define FSS_PERSISTENT 0x20 /* File system internal snapshot */
#define FSS_CDEV_OPEN 0x40 /* character device open */
#define FSS_BDEV_OPEN 0x80 /* block device open */