Module Name: src Committed By: hannken Date: Sun May 28 16:35:47 UTC 2017
Modified Files: src/sys/kern: vfs_vnode.c Log Message: Add a helper to propagate file system suspension for vrevoke(). Take care to retry suspension on interrupt as vrevoke must succeed. To generate a diff of this commit: cvs rdiff -u -r1.91 -r1.92 src/sys/kern/vfs_vnode.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_vnode.c diff -u src/sys/kern/vfs_vnode.c:1.91 src/sys/kern/vfs_vnode.c:1.92 --- src/sys/kern/vfs_vnode.c:1.91 Fri May 26 14:40:09 2017 +++ src/sys/kern/vfs_vnode.c Sun May 28 16:35:47 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.91 2017/05/26 14:40:09 riastradh Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.92 2017/05/28 16:35:47 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.91 2017/05/26 14:40:09 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.92 2017/05/28 16:35:47 hannken Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -944,13 +944,42 @@ vrecycle(vnode_t *vp) } /* + * Helper for vrevoke() to propagate suspension from lastmp + * to thismp. Both args may be NULL. + * Returns the currently suspended file system or NULL. + */ +static struct mount * +vrevoke_suspend_next(struct mount *lastmp, struct mount *thismp) +{ + int error; + + if (lastmp == thismp) + return thismp; + + if (lastmp != NULL) + vfs_resume(lastmp); + + if (thismp == NULL) + return NULL; + + do { + error = vfs_suspend(thismp, 0); + } while (error == EINTR || error == ERESTART); + + if (error == 0) + return thismp; + + KASSERT(error == EOPNOTSUPP); + return NULL; +} + +/* * Eliminate all activity associated with the requested vnode * and with all vnodes aliased to the requested vnode. */ void vrevoke(vnode_t *vp) { - int error; struct mount *mp; vnode_t *vq; enum vtype type; @@ -958,11 +987,7 @@ vrevoke(vnode_t *vp) KASSERT(vp->v_usecount > 0); - mp = vp->v_mount; - error = vfs_suspend(mp, 0); - KASSERT(error == 0 || error == EOPNOTSUPP); - if (error) - mp = NULL; + mp = vrevoke_suspend_next(NULL, vp->v_mount); mutex_enter(vp->v_interlock); VSTATE_WAIT_STABLE(vp); @@ -978,20 +1003,11 @@ vrevoke(vnode_t *vp) mutex_exit(vp->v_interlock); while (spec_node_lookup_by_dev(type, dev, &vq) == 0) { - if (mp != vq->v_mount) { - if (mp) - vfs_resume(mp); - mp = vp->v_mount; - error = vfs_suspend(mp, 0); - KASSERT(error == 0 || error == EOPNOTSUPP); - if (error) - mp = NULL; - } + mp = vrevoke_suspend_next(mp, vq->v_mount); vgone(vq); } } - if (mp) - vfs_resume(mp); + vrevoke_suspend_next(mp, NULL); } /*