Module Name: src
Committed By: hannken
Date: Wed Aug 29 09:04:03 UTC 2018
Modified Files:
src/sys/dev: fss.c fssvar.h
Log Message:
Convert flags FSS_ACTIVE and FSS_ERROR into new member sc_state
with states FSS_IDLE, FSS_ACTIVE and FSS_ERROR.
No functional change intended.
To generate a diff of this commit:
cvs rdiff -u -r1.104 -r1.105 src/sys/dev/fss.c
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/fssvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/fss.c
diff -u src/sys/dev/fss.c:1.104 src/sys/dev/fss.c:1.105
--- src/sys/dev/fss.c:1.104 Tue Jan 23 22:42:29 2018
+++ src/sys/dev/fss.c Wed Aug 29 09:04:03 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fss.c,v 1.104 2018/01/23 22:42:29 pgoyette Exp $ */
+/* $NetBSD: fss.c,v 1.105 2018/08/29 09:04:03 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.104 2018/01/23 22:42:29 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.105 2018/08/29 09:04:03 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -173,8 +173,12 @@ fss_detach(device_t self, int flags)
{
struct fss_softc *sc = device_private(self);
- if (sc->sc_flags & FSS_ACTIVE)
+ mutex_enter(&sc->sc_slock);
+ if (sc->sc_state != FSS_IDLE) {
+ mutex_exit(&sc->sc_slock);
return EBUSY;
+ }
+ mutex_exit(&sc->sc_slock);
if (--fss_num_attached == 0)
vfs_hooks_detach(&fss_vfs_hooks);
@@ -215,6 +219,7 @@ fss_open(dev_t dev, int flags, int mode,
mutex_exit(&fss_device_lock);
return ENOMEM;
}
+ sc->sc_state = FSS_IDLE;
}
mutex_enter(&sc->sc_slock);
@@ -246,20 +251,20 @@ restart:
mutex_exit(&fss_device_lock);
return 0;
}
- if ((sc->sc_flags & FSS_ACTIVE) != 0 &&
+ if (sc->sc_state != FSS_IDLE &&
(sc->sc_uflags & FSS_UNCONFIG_ON_CLOSE) != 0) {
sc->sc_uflags &= ~FSS_UNCONFIG_ON_CLOSE;
mutex_exit(&sc->sc_slock);
error = fss_ioctl(dev, FSSIOCCLR, NULL, FWRITE, l);
goto restart;
}
- if ((sc->sc_flags & FSS_ACTIVE) != 0) {
+ if (sc->sc_state != FSS_IDLE) {
mutex_exit(&sc->sc_slock);
mutex_exit(&fss_device_lock);
return error;
}
- KASSERT((sc->sc_flags & FSS_ACTIVE) == 0);
+ KASSERT(sc->sc_state == FSS_IDLE);
KASSERT((sc->sc_flags & (FSS_CDEV_OPEN|FSS_BDEV_OPEN)) == mflag);
mutex_exit(&sc->sc_slock);
cf = device_cfdata(sc->sc_dev);
@@ -279,7 +284,7 @@ fss_strategy(struct buf *bp)
mutex_enter(&sc->sc_slock);
- if (write || !FSS_ISVALID(sc)) {
+ if (write || sc->sc_state != FSS_ACTIVE) {
bp->b_error = (write ? EROFS : ENXIO);
goto done;
}
@@ -317,7 +322,7 @@ fss_write(dev_t dev, struct uio *uio, in
int
fss_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
- int error;
+ int error = 0;
struct fss_softc *sc = device_lookup_private(&fss_cd, minor(dev));
struct fss_set _fss;
struct fss_set *fss = (struct fss_set *)data;
@@ -339,9 +344,11 @@ fss_ioctl(dev_t dev, u_long cmd, void *d
mutex_enter(&sc->sc_lock);
if ((flag & FWRITE) == 0)
error = EPERM;
- else if ((sc->sc_flags & FSS_ACTIVE) != 0)
+ mutex_enter(&sc->sc_slock);
+ if (error == 0 && sc->sc_state != FSS_IDLE)
error = EBUSY;
- else
+ mutex_exit(&sc->sc_slock);
+ if (error == 0)
error = fss_create_snapshot(sc, fss, l);
if (error == 0)
sc->sc_uflags = fss->fss_flags;
@@ -352,9 +359,11 @@ fss_ioctl(dev_t dev, u_long cmd, void *d
mutex_enter(&sc->sc_lock);
if ((flag & FWRITE) == 0)
error = EPERM;
- else if ((sc->sc_flags & FSS_ACTIVE) == 0)
+ mutex_enter(&sc->sc_slock);
+ if (error == 0 && sc->sc_state == FSS_IDLE)
error = ENXIO;
- else
+ mutex_exit(&sc->sc_slock);
+ if (error == 0)
error = fss_delete_snapshot(sc, l);
mutex_exit(&sc->sc_lock);
break;
@@ -362,54 +371,50 @@ fss_ioctl(dev_t dev, u_long cmd, void *d
#ifndef _LP64
case FSSIOCGET50:
mutex_enter(&sc->sc_lock);
- switch (sc->sc_flags & (FSS_PERSISTENT | FSS_ACTIVE)) {
- case FSS_ACTIVE:
+ mutex_enter(&sc->sc_slock);
+ if (sc->sc_state == FSS_IDLE) {
+ error = ENXIO;
+ } else if ((sc->sc_flags & FSS_PERSISTENT) == 0) {
memcpy(fsg50->fsg_mount, sc->sc_mntname, MNAMELEN);
fsg50->fsg_csize = FSS_CLSIZE(sc);
timeval_to_timeval50(&sc->sc_time, &fsg50->fsg_time);
fsg50->fsg_mount_size = sc->sc_clcount;
fsg50->fsg_bs_size = sc->sc_clnext;
error = 0;
- break;
- case FSS_PERSISTENT | FSS_ACTIVE:
+ } else {
memcpy(fsg50->fsg_mount, sc->sc_mntname, MNAMELEN);
fsg50->fsg_csize = 0;
timeval_to_timeval50(&sc->sc_time, &fsg50->fsg_time);
fsg50->fsg_mount_size = 0;
fsg50->fsg_bs_size = 0;
error = 0;
- break;
- default:
- error = ENXIO;
- break;
}
+ mutex_exit(&sc->sc_slock);
mutex_exit(&sc->sc_lock);
break;
#endif /* _LP64 */
case FSSIOCGET:
mutex_enter(&sc->sc_lock);
- switch (sc->sc_flags & (FSS_PERSISTENT | FSS_ACTIVE)) {
- case FSS_ACTIVE:
+ mutex_enter(&sc->sc_slock);
+ if (sc->sc_state == FSS_IDLE) {
+ error = ENXIO;
+ } else if ((sc->sc_flags & FSS_PERSISTENT) == 0) {
memcpy(fsg->fsg_mount, sc->sc_mntname, MNAMELEN);
fsg->fsg_csize = FSS_CLSIZE(sc);
fsg->fsg_time = sc->sc_time;
fsg->fsg_mount_size = sc->sc_clcount;
fsg->fsg_bs_size = sc->sc_clnext;
error = 0;
- break;
- case FSS_PERSISTENT | FSS_ACTIVE:
+ } else {
memcpy(fsg->fsg_mount, sc->sc_mntname, MNAMELEN);
fsg->fsg_csize = 0;
fsg->fsg_time = sc->sc_time;
fsg->fsg_mount_size = 0;
fsg->fsg_bs_size = 0;
error = 0;
- break;
- default:
- error = ENXIO;
- break;
}
+ mutex_exit(&sc->sc_slock);
mutex_exit(&sc->sc_lock);
break;
@@ -457,13 +462,18 @@ static inline void
fss_error(struct fss_softc *sc, const char *msg)
{
- if ((sc->sc_flags & (FSS_ACTIVE | FSS_ERROR)) != FSS_ACTIVE)
+ KASSERT(mutex_owned(&sc->sc_slock));
+
+ if (sc->sc_state == FSS_ERROR)
return;
aprint_error_dev(sc->sc_dev, "snapshot invalid: %s\n", msg);
- if ((sc->sc_flags & FSS_PERSISTENT) == 0)
+ if ((sc->sc_flags & FSS_PERSISTENT) == 0) {
+ mutex_exit(&sc->sc_slock);
fscow_disestablish(sc->sc_mount, fss_copy_on_write, sc);
- sc->sc_flags |= FSS_ERROR;
+ mutex_enter(&sc->sc_slock);
+ }
+ sc->sc_state = FSS_ERROR;
}
/*
@@ -570,7 +580,7 @@ fss_unmount_hook(struct mount *mp)
if ((sc = device_lookup_private(&fss_cd, i)) == NULL)
continue;
mutex_enter(&sc->sc_slock);
- if ((sc->sc_flags & FSS_ACTIVE) != 0 && sc->sc_mount == mp)
+ if (sc->sc_state != FSS_IDLE && sc->sc_mount == mp)
fss_error(sc, "forced by unmount");
mutex_exit(&sc->sc_slock);
}
@@ -589,7 +599,7 @@ fss_copy_on_write(void *v, struct buf *b
struct fss_softc *sc = v;
mutex_enter(&sc->sc_slock);
- if (!FSS_ISVALID(sc)) {
+ if (sc->sc_state != FSS_ACTIVE) {
mutex_exit(&sc->sc_slock);
return 0;
}
@@ -782,7 +792,9 @@ fss_create_snapshot(struct fss_softc *sc
if (sc->sc_flags & FSS_PERSISTENT) {
fss_softc_alloc(sc);
- sc->sc_flags |= FSS_ACTIVE;
+ mutex_enter(&sc->sc_slock);
+ sc->sc_state = FSS_ACTIVE;
+ mutex_exit(&sc->sc_slock);
return 0;
}
@@ -847,8 +859,11 @@ fss_create_snapshot(struct fss_softc *sc
error = VFS_SYNC(sc->sc_mount, MNT_WAIT, curlwp->l_cred);
if (error == 0)
error = fscow_establish(sc->sc_mount, fss_copy_on_write, sc);
- if (error == 0)
- sc->sc_flags |= FSS_ACTIVE;
+ if (error == 0) {
+ mutex_enter(&sc->sc_slock);
+ sc->sc_state = FSS_ACTIVE;
+ mutex_exit(&sc->sc_slock);
+ }
vfs_resume(sc->sc_mount);
@@ -883,11 +898,13 @@ static int
fss_delete_snapshot(struct fss_softc *sc, struct lwp *l)
{
- if ((sc->sc_flags & (FSS_PERSISTENT | FSS_ERROR)) == 0)
- fscow_disestablish(sc->sc_mount, fss_copy_on_write, sc);
-
mutex_enter(&sc->sc_slock);
- sc->sc_flags &= ~(FSS_ACTIVE|FSS_ERROR);
+ if ((sc->sc_flags & FSS_PERSISTENT) == 0 && sc->sc_state != FSS_ERROR) {
+ mutex_exit(&sc->sc_slock);
+ fscow_disestablish(sc->sc_mount, fss_copy_on_write, sc);
+ mutex_enter(&sc->sc_slock);
+ }
+ sc->sc_state = FSS_IDLE;
sc->sc_mount = NULL;
sc->sc_bdev = NODEV;
mutex_exit(&sc->sc_slock);
@@ -922,7 +939,7 @@ fss_read_cluster(struct fss_softc *sc, u
mutex_enter(&sc->sc_slock);
restart:
- if (isset(sc->sc_copied, cl) || !FSS_ISVALID(sc)) {
+ if (isset(sc->sc_copied, cl) || sc->sc_state != FSS_ACTIVE) {
mutex_exit(&sc->sc_slock);
return 0;
}
@@ -1108,7 +1125,7 @@ fss_bs_thread(void *arg)
if (sc->sc_flags & FSS_PERSISTENT) {
if ((bp = bufq_get(sc->sc_bufq)) == NULL)
continue;
- is_valid = FSS_ISVALID(sc);
+ is_valid = (sc->sc_state == FSS_ACTIVE);
is_read = (bp->b_flags & B_READ);
thread_idle = false;
mutex_exit(&sc->sc_slock);
@@ -1170,7 +1187,7 @@ fss_bs_thread(void *arg)
*/
if ((bp = bufq_get(sc->sc_bufq)) == NULL)
continue;
- is_valid = FSS_ISVALID(sc);
+ is_valid = (sc->sc_state == FSS_ACTIVE);
is_read = (bp->b_flags & B_READ);
thread_idle = false;
Index: src/sys/dev/fssvar.h
diff -u src/sys/dev/fssvar.h:1.29 src/sys/dev/fssvar.h:1.30
--- src/sys/dev/fssvar.h:1.29 Sun Sep 6 06:00:59 2015
+++ src/sys/dev/fssvar.h Wed Aug 29 09:04:03 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fssvar.h,v 1.29 2015/09/06 06:00:59 dholland Exp $ */
+/* $NetBSD: fssvar.h,v 1.30 2018/08/29 09:04:03 hannken Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -83,10 +83,6 @@ struct fss_get50 {
sc_copied map uses up to
FSS_CLUSTER_MAX/NBBY bytes */
-/* Check if still valid */
-#define FSS_ISVALID(sc) \
- (((sc)->sc_flags & (FSS_ACTIVE|FSS_ERROR)) == FSS_ACTIVE)
-
/* Offset to cluster */
#define FSS_BTOCL(sc, off) \
((off) >> (sc)->sc_clshift)
@@ -137,15 +133,20 @@ struct fss_cache {
void * fc_data; /* Data */
};
+typedef enum {
+ FSS_IDLE, /* Device is unconfigured */
+ FSS_ACTIVE, /* Device is configured */
+ FSS_ERROR /* Device had errors */
+} fss_state_t;
+
struct fss_softc {
device_t sc_dev; /* Self */
kmutex_t sc_slock; /* Protect this softc */
kmutex_t sc_lock; /* Sleep lock for fss_ioctl */
kcondvar_t sc_work_cv; /* Signals work for the kernel thread */
kcondvar_t sc_cache_cv; /* Signals free cache slot */
+ fss_state_t sc_state; /* Current state */
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_PERSISTENT 0x20 /* File system internal snapshot */
#define FSS_CDEV_OPEN 0x40 /* character device open */