Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Add a helper to propagate file system suspension fo...



details:   https://anonhg.NetBSD.org/src/rev/3be3e45ba3a1
branches:  trunk
changeset: 824223:3be3e45ba3a1
user:      hannken <hannken%NetBSD.org@localhost>
date:      Sun May 28 16:35:47 2017 +0000

description:
Add a helper to propagate file system suspension for vrevoke().

Take care to retry suspension on interrupt as vrevoke must succeed.

diffstat:

 sys/kern/vfs_vnode.c |  54 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diffs (98 lines):

diff -r 3cbbc42dc5ac -r 3be3e45ba3a1 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Sun May 28 15:55:11 2017 +0000
+++ b/sys/kern/vfs_vnode.c      Sun May 28 16:35:47 2017 +0000
@@ -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 @@
 }
 
 /*
+ * 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 @@
 
        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 @@
                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);
 }
 
 /*



Home | Main Index | Thread Index | Old Index