summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorhannken <hannken@NetBSD.org>2018-10-05 09:51:55 +0000
committerhannken <hannken@NetBSD.org>2018-10-05 09:51:55 +0000
commitc71e1b358db5f10db830d91bf236808488e39d44 (patch)
tree8200f2bcd311c91ff3338a81a7cd2562f3f57a0e /sys
parentc750c00481d89810731b1627417c05d66a7b012e (diff)
Bring back three state file system suspension:
NORMAL -> SUSPENDING -> SUSPENDED and add operation fstrans_start_lazy() that only blocks while SUSPENDED. Change vndthread() support operation handle_with_rdwr() to bracket its file system operations by fstrans_start_lazy() and fstrans_done(). PR kern/53624 (dom0 freeze on domU exit)
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/vnd.c10
-rw-r--r--sys/kern/vfs_trans.c22
-rw-r--r--sys/miscfs/genfs/genfs_vfsops.c7
-rw-r--r--sys/rump/librump/rumpkern/emul.c13
-rw-r--r--sys/sys/fstrans.h6
5 files changed, 48 insertions, 10 deletions
diff --git a/sys/dev/vnd.c b/sys/dev/vnd.c
index 587a9bb3260..38439695cf3 100644
--- a/sys/dev/vnd.c
+++ b/sys/dev/vnd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vnd.c,v 1.265 2018/09/20 07:18:38 mlelstv Exp $ */
+/* $NetBSD: vnd.c,v 1.266 2018/10/05 09:51:55 hannken Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.265 2018/09/20 07:18:38 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.266 2018/10/05 09:51:55 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_vnd.h"
@@ -114,6 +114,7 @@ __KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.265 2018/09/20 07:18:38 mlelstv Exp $");
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/vnode.h>
+#include <sys/fstrans.h>
#include <sys/file.h>
#include <sys/uio.h>
#include <sys/conf.h>
@@ -802,6 +803,9 @@ handle_with_rdwr(struct vnd_softc *vnd, const struct buf *obp, struct buf *bp)
bp->b_bcount);
#endif
+ /* Make sure the request succeeds while suspending this fs. */
+ fstrans_start_lazy(vp->v_mount);
+
/* Issue the read or write operation. */
bp->b_error =
vn_rdwr(doread ? UIO_READ : UIO_WRITE,
@@ -813,6 +817,8 @@ handle_with_rdwr(struct vnd_softc *vnd, const struct buf *obp, struct buf *bp)
(void) VOP_PUTPAGES(vp, 0, 0,
PGO_ALLPAGES | PGO_CLEANIT | PGO_FREE | PGO_SYNCIO);
+ fstrans_done(vp->v_mount);
+
/* We need to increase the number of outputs on the vnode if
* there was any write to it. */
if (!doread) {
diff --git a/sys/kern/vfs_trans.c b/sys/kern/vfs_trans.c
index 3edde926e26..c8f75bebf47 100644
--- a/sys/kern/vfs_trans.c
+++ b/sys/kern/vfs_trans.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_trans.c,v 1.50 2018/10/05 01:25:38 manu Exp $ */
+/* $NetBSD: vfs_trans.c,v 1.51 2018/10/05 09:51:55 hannken Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.50 2018/10/05 01:25:38 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.51 2018/10/05 09:51:55 hannken Exp $");
/*
* File system transaction operations.
@@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.50 2018/10/05 01:25:38 manu Exp $");
#include <miscfs/specfs/specdev.h>
enum fstrans_lock_type {
+ FSTRANS_LAZY, /* Granted while not suspended */
FSTRANS_SHARED, /* Granted while not suspending */
FSTRANS_EXCL /* Internal: exclusive lock */
};
@@ -342,6 +343,8 @@ grant_lock(const enum fstrans_state state, const enum fstrans_lock_type type)
return true;
if (type == FSTRANS_EXCL)
return true;
+ if (state == FSTRANS_SUSPENDING && type == FSTRANS_LAZY)
+ return true;
return false;
}
@@ -422,6 +425,15 @@ fstrans_start_nowait(struct mount *mp)
return _fstrans_start(mp, FSTRANS_SHARED, 0);
}
+void
+fstrans_start_lazy(struct mount *mp)
+{
+ int error __diagused;
+
+ error = _fstrans_start(mp, FSTRANS_LAZY, 1);
+ KASSERT(error == 0);
+}
+
/*
* Finish a transaction.
*/
@@ -849,6 +861,9 @@ fstrans_print_lwp(struct proc *p, struct lwp *l, int verbose)
printf(" -");
} else {
switch (fli->fli_lock_type) {
+ case FSTRANS_LAZY:
+ printf(" lazy");
+ break;
case FSTRANS_SHARED:
printf(" shared");
break;
@@ -883,6 +898,9 @@ fstrans_print_mount(struct mount *mp, int verbose)
case FSTRANS_NORMAL:
printf("state normal\n");
break;
+ case FSTRANS_SUSPENDING:
+ printf("state suspending\n");
+ break;
case FSTRANS_SUSPENDED:
printf("state suspended\n");
break;
diff --git a/sys/miscfs/genfs/genfs_vfsops.c b/sys/miscfs/genfs/genfs_vfsops.c
index 281e5e4e11f..33e3d7e3d9e 100644
--- a/sys/miscfs/genfs/genfs_vfsops.c
+++ b/sys/miscfs/genfs/genfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_vfsops.c,v 1.7 2017/05/24 09:53:55 hannken Exp $ */
+/* $NetBSD: genfs_vfsops.c,v 1.8 2018/10/05 09:51:55 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_vfsops.c,v 1.7 2017/05/24 09:53:55 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_vfsops.c,v 1.8 2018/10/05 09:51:55 hannken Exp $");
#include <sys/types.h>
#include <sys/mount.h>
@@ -83,6 +83,9 @@ genfs_suspendctl(struct mount *mp, int cmd)
switch (cmd) {
case SUSPEND_SUSPEND:
+ error = fstrans_setstate(mp, FSTRANS_SUSPENDING);
+ if (error)
+ return error;
error = fstrans_setstate(mp, FSTRANS_SUSPENDED);
if (error == 0) {
if ((mp->mnt_iflag & IMNT_GONE) != 0)
diff --git a/sys/rump/librump/rumpkern/emul.c b/sys/rump/librump/rumpkern/emul.c
index 88ebf8b841e..4028b2c418b 100644
--- a/sys/rump/librump/rumpkern/emul.c
+++ b/sys/rump/librump/rumpkern/emul.c
@@ -1,4 +1,4 @@
-/* $NetBSD: emul.c,v 1.186 2018/08/10 21:44:59 pgoyette Exp $ */
+/* $NetBSD: emul.c,v 1.187 2018/10/05 09:51:55 hannken Exp $ */
/*
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.186 2018/08/10 21:44:59 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.187 2018/10/05 09:51:55 hannken Exp $");
#include <sys/param.h>
#include <sys/cprng.h>
@@ -275,6 +275,15 @@ rump_fstrans_start_nowait(struct mount *mp)
}
__weak_alias(fstrans_start_nowait,rump_fstrans_start_nowait);
+void rump_fstrans_start_lazy(struct mount *);
+void
+rump_fstrans_start_lazy(struct mount *mp)
+{
+
+}
+__weak_alias(fstrans_start_lazy,rump_fstrans_start_lazy);
+
+
void rump_fstrans_done(struct mount *);
void
rump_fstrans_done(struct mount *mp)
diff --git a/sys/sys/fstrans.h b/sys/sys/fstrans.h
index c1889d080de..3eb522827e2 100644
--- a/sys/sys/fstrans.h
+++ b/sys/sys/fstrans.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fstrans.h,v 1.11 2017/06/04 08:05:42 hannken Exp $ */
+/* $NetBSD: fstrans.h,v 1.12 2018/10/05 09:51:56 hannken Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -43,12 +43,14 @@
enum fstrans_state {
FSTRANS_NORMAL,
- FSTRANS_SUSPENDED
+ FSTRANS_SUSPENDED,
+ FSTRANS_SUSPENDING
};
void fstrans_init(void);
void fstrans_start(struct mount *);
int fstrans_start_nowait(struct mount *);
+void fstrans_start_lazy(struct mount *);
void fstrans_done(struct mount *);
int fstrans_is_owner(struct mount *);
int fstrans_mount(struct mount *);