Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Vrecycle() cannot wait for the vnode lock. On a le...
details: https://anonhg.NetBSD.org/src/rev/76ba2a6bfeb3
branches: trunk
changeset: 350932:76ba2a6bfeb3
user: hannken <hannken%NetBSD.org@localhost>
date: Fri Jan 27 10:50:10 2017 +0000
description:
Vrecycle() cannot wait for the vnode lock. On a leaf file system this lock
will always succeed as we hold the last reference and prevent further
references. On layered file systems waiting for the lock would open a can of
deadlocks as the lower vnodes may have other active references.
diffstat:
sys/kern/vfs_mount.c | 41 +++++++++++++++++++++++------------------
sys/kern/vfs_vnode.c | 18 ++++++++++++++----
2 files changed, 37 insertions(+), 22 deletions(-)
diffs (113 lines):
diff -r bac1ddfeb849 -r 76ba2a6bfeb3 sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c Fri Jan 27 10:48:51 2017 +0000
+++ b/sys/kern/vfs_mount.c Fri Jan 27 10:50:10 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_mount.c,v 1.46 2017/01/27 10:46:18 hannken Exp $ */
+/* $NetBSD: vfs_mount.c,v 1.47 2017/01/27 10:50:10 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.46 2017/01/27 10:46:18 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.47 2017/01/27 10:50:10 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -551,30 +551,35 @@
{
vnode_t *vp;
struct vnode_iterator *marker;
- int busy, error, when;
+ int busy, error, when, retries = 2;
- busy = error = when = 0;
+ do {
+ busy = error = when = 0;
- /* First, flush out any vnode references from deferred vrele list. */
- vfs_drainvnodes();
+ /*
+ * First, flush out any vnode references from the
+ * deferred vrele list.
+ */
+ vfs_drainvnodes();
- vfs_vnode_iterator_init(mp, &marker);
+ vfs_vnode_iterator_init(mp, &marker);
- while ((vp = vflushnext(marker, &when)) != NULL) {
- error = vflush_one(vp, skipvp, flags);
- if (error == EBUSY) {
- error = 0;
- busy++;
+ while ((vp = vflushnext(marker, &when)) != NULL) {
+ error = vflush_one(vp, skipvp, flags);
+ if (error == EBUSY) {
+ error = 0;
+ busy++;
#ifdef DEBUG
- if (busyprt)
- vprint("vflush: busy vnode", vp);
+ if (busyprt && retries == 0)
+ vprint("vflush: busy vnode", vp);
#endif
- } else if (error != 0) {
- break;
+ } else if (error != 0) {
+ break;
+ }
}
- }
- vfs_vnode_iterator_destroy(marker);
+ vfs_vnode_iterator_destroy(marker);
+ } while (error == 0 && busy > 0 && retries-- > 0);
if (error)
return error;
diff -r bac1ddfeb849 -r 76ba2a6bfeb3 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Fri Jan 27 10:48:51 2017 +0000
+++ b/sys/kern/vfs_vnode.c Fri Jan 27 10:50:10 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.72 2017/01/11 09:08:58 hannken Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.73 2017/01/27 10:50:10 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -156,7 +156,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.72 2017/01/11 09:08:58 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.73 2017/01/27 10:50:10 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -872,12 +872,22 @@
VSTATE_CHANGE(vp, VS_ACTIVE, VS_BLOCKED);
mutex_exit(vp->v_interlock);
- error = vn_lock(vp, LK_EXCLUSIVE);
- KASSERT(error == 0);
+ /*
+ * On a leaf file system this lock will always succeed as we hold
+ * the last reference and prevent further references.
+ * On layered file systems waiting for the lock would open a can of
+ * deadlocks as the lower vnodes may have other active references.
+ */
+ error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
mutex_enter(vp->v_interlock);
VSTATE_CHANGE(vp, VS_BLOCKED, VS_ACTIVE);
+ if (error) {
+ mutex_exit(vp->v_interlock);
+ return false;
+ }
+
KASSERT(vp->v_usecount == 1);
vcache_reclaim(vp);
vrelel(vp, 0);
Home |
Main Index |
Thread Index |
Old Index