Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add two new states FSS_CREATING and FSS_DESTROYING a...
details: https://anonhg.NetBSD.org/src/rev/dbf880b36e3d
branches: trunk
changeset: 364958:dbf880b36e3d
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Aug 29 09:04:40 2018 +0000
description:
Add two new states FSS_CREATING and FSS_DESTROYING and use them
while creating or destroying a snapshot.
Remove now unneeded sc_lock that made fss_ioctl mutually exclusive.
Fss_ioctl no longer blocks forever because a snapshot gets
created or destroyed.
Serialize snapshot creation and make it interruptible.
diffstat:
sys/dev/fss.c | 106 ++++++++++++++++++++++++++++++++++++++++--------------
sys/dev/fssvar.h | 5 +-
2 files changed, 81 insertions(+), 30 deletions(-)
diffs (243 lines):
diff -r 38153488cd77 -r dbf880b36e3d sys/dev/fss.c
--- a/sys/dev/fss.c Wed Aug 29 09:04:03 2018 +0000
+++ b/sys/dev/fss.c Wed Aug 29 09:04:40 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fss.c,v 1.105 2018/08/29 09:04:03 hannken Exp $ */
+/* $NetBSD: fss.c,v 1.106 2018/08/29 09:04:40 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.105 2018/08/29 09:04:03 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.106 2018/08/29 09:04:40 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -93,6 +93,8 @@
static u_int32_t *fss_bs_indir(struct fss_softc *, u_int32_t);
static kmutex_t fss_device_lock; /* Protect all units. */
+static kcondvar_t fss_device_cv; /* Serialize snapshot creation. */
+static bool fss_creating = false; /* Currently creating a snapshot. */
static int fss_num_attached = 0; /* Number of attached devices. */
static struct vfs_hooks fss_vfs_hooks = {
.vh_unmount = fss_unmount_hook
@@ -136,6 +138,7 @@
{
mutex_init(&fss_device_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&fss_device_cv, "snapwait");
if (config_cfattach_attach(fss_cd.cd_name, &fss_ca))
aprint_error("%s: unable to register\n", fss_cd.cd_name);
}
@@ -154,7 +157,6 @@
sc->sc_dev = self;
sc->sc_bdev = NODEV;
mutex_init(&sc->sc_slock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&sc->sc_work_cv, "fssbs");
cv_init(&sc->sc_cache_cv, "cowwait");
bufq_alloc(&sc->sc_bufq, "fcfs", 0);
@@ -185,7 +187,6 @@
pmf_device_deregister(self);
mutex_destroy(&sc->sc_slock);
- mutex_destroy(&sc->sc_lock);
cv_destroy(&sc->sc_work_cv);
cv_destroy(&sc->sc_cache_cv);
bufq_drain(sc->sc_bufq);
@@ -341,36 +342,83 @@
fss->fss_flags = 0;
/* Fall through */
case FSSIOCSET:
- mutex_enter(&sc->sc_lock);
+ mutex_enter(&sc->sc_slock);
if ((flag & FWRITE) == 0)
error = EPERM;
- mutex_enter(&sc->sc_slock);
- if (error == 0 && sc->sc_state != FSS_IDLE)
+ if (error == 0 && sc->sc_state != FSS_IDLE) {
error = EBUSY;
+ } else {
+ sc->sc_state = FSS_CREATING;
+ copyinstr(fss->fss_mount, sc->sc_mntname,
+ sizeof(sc->sc_mntname), NULL);
+ memset(&sc->sc_time, 0, sizeof(sc->sc_time));
+ sc->sc_clshift = 0;
+ }
mutex_exit(&sc->sc_slock);
- if (error == 0)
- error = fss_create_snapshot(sc, fss, l);
- if (error == 0)
+ if (error)
+ break;
+
+ /*
+ * Serialize snapshot creation.
+ */
+ mutex_enter(&fss_device_lock);
+ while (fss_creating) {
+ error = cv_wait_sig(&fss_device_cv, &fss_device_lock);
+ if (error) {
+ mutex_enter(&sc->sc_slock);
+ KASSERT(sc->sc_state == FSS_CREATING);
+ sc->sc_state = FSS_IDLE;
+ mutex_exit(&sc->sc_slock);
+ mutex_exit(&fss_device_lock);
+ break;
+ }
+ }
+ fss_creating = true;
+ mutex_exit(&fss_device_lock);
+
+ error = fss_create_snapshot(sc, fss, l);
+ mutex_enter(&sc->sc_slock);
+ if (error == 0) {
+ KASSERT(sc->sc_state == FSS_ACTIVE);
sc->sc_uflags = fss->fss_flags;
- mutex_exit(&sc->sc_lock);
+ } else {
+ KASSERT(sc->sc_state == FSS_CREATING);
+ sc->sc_state = FSS_IDLE;
+ }
+ mutex_exit(&sc->sc_slock);
+
+ mutex_enter(&fss_device_lock);
+ fss_creating = false;
+ cv_broadcast(&fss_device_cv);
+ mutex_exit(&fss_device_lock);
+
break;
case FSSIOCCLR:
- mutex_enter(&sc->sc_lock);
- if ((flag & FWRITE) == 0)
- error = EPERM;
mutex_enter(&sc->sc_slock);
- if (error == 0 && sc->sc_state == FSS_IDLE)
- error = ENXIO;
+ if ((flag & FWRITE) == 0) {
+ error = EPERM;
+ } else if (sc->sc_state != FSS_ACTIVE &&
+ sc->sc_state != FSS_ERROR) {
+ error = EBUSY;
+ } else {
+ sc->sc_state = FSS_DESTROYING;
+ }
mutex_exit(&sc->sc_slock);
- if (error == 0)
- error = fss_delete_snapshot(sc, l);
- mutex_exit(&sc->sc_lock);
+ if (error)
+ break;
+
+ error = fss_delete_snapshot(sc, l);
+ mutex_enter(&sc->sc_slock);
+ if (error)
+ fss_error(sc, "Failed to delete snapshot");
+ else
+ KASSERT(sc->sc_state == FSS_IDLE);
+ mutex_exit(&sc->sc_slock);
break;
#ifndef _LP64
case FSSIOCGET50:
- mutex_enter(&sc->sc_lock);
mutex_enter(&sc->sc_slock);
if (sc->sc_state == FSS_IDLE) {
error = ENXIO;
@@ -390,12 +438,10 @@
error = 0;
}
mutex_exit(&sc->sc_slock);
- mutex_exit(&sc->sc_lock);
break;
#endif /* _LP64 */
case FSSIOCGET:
- mutex_enter(&sc->sc_lock);
mutex_enter(&sc->sc_slock);
if (sc->sc_state == FSS_IDLE) {
error = ENXIO;
@@ -415,7 +461,6 @@
error = 0;
}
mutex_exit(&sc->sc_slock);
- mutex_exit(&sc->sc_lock);
break;
case FSSIOFSET:
@@ -902,20 +947,23 @@
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);
+ } else {
+ mutex_exit(&sc->sc_slock);
}
- sc->sc_state = FSS_IDLE;
- sc->sc_mount = NULL;
- sc->sc_bdev = NODEV;
- mutex_exit(&sc->sc_slock);
fss_softc_free(sc);
if (sc->sc_flags & FSS_PERSISTENT)
vrele(sc->sc_bs_vp);
else
vn_close(sc->sc_bs_vp, FREAD|FWRITE, l->l_cred);
+
+ mutex_enter(&sc->sc_slock);
+ sc->sc_state = FSS_IDLE;
+ sc->sc_mount = NULL;
+ sc->sc_bdev = NODEV;
sc->sc_bs_vp = NULL;
sc->sc_flags &= ~FSS_PERSISTENT;
+ mutex_exit(&sc->sc_slock);
return 0;
}
@@ -1323,6 +1371,7 @@
switch (cmd) {
case MODULE_CMD_INIT:
mutex_init(&fss_device_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&fss_device_cv, "snapwait");
error = config_cfdriver_attach(&fss_cd);
if (error) {
mutex_destroy(&fss_device_lock);
@@ -1361,6 +1410,7 @@
&fss_cdevsw, &fss_cmajor);
break;
}
+ cv_destroy(&fss_device_cv);
mutex_destroy(&fss_device_lock);
break;
diff -r 38153488cd77 -r dbf880b36e3d sys/dev/fssvar.h
--- a/sys/dev/fssvar.h Wed Aug 29 09:04:03 2018 +0000
+++ b/sys/dev/fssvar.h Wed Aug 29 09:04:40 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fssvar.h,v 1.30 2018/08/29 09:04:03 hannken Exp $ */
+/* $NetBSD: fssvar.h,v 1.31 2018/08/29 09:04:40 hannken Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -135,14 +135,15 @@
typedef enum {
FSS_IDLE, /* Device is unconfigured */
+ FSS_CREATING, /* Device is currently configuring */
FSS_ACTIVE, /* Device is configured */
+ FSS_DESTROYING, /* Device is currently unconfiguring */
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 */
Home |
Main Index |
Thread Index |
Old Index