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.
This commit is contained in:
parent
ae84301430
commit
3b7a4338db
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user