Source-Changes-HG archive

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

[src/trunk]: src Introduce a selector function to the vfs vnode iterator so t...



details:   https://anonhg.NetBSD.org/src/rev/3ea918660cd5
branches:  trunk
changeset: 329444:3ea918660cd5
user:      christos <christos%NetBSD.org@localhost>
date:      Sat May 24 16:34:03 2014 +0000

description:
Introduce a selector function to the vfs vnode iterator so that we don't
need to vget() vnodes that we are not interested at, and optimize locking
a bit. Iterator changes reviewed by Hannken (thanks), the rest of the bugs
are mine.

diffstat:

 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c |   26 ++-
 share/man/man9/vfssubr.9                                |   38 +++--
 sys/fs/msdosfs/msdosfs_vfsops.c                         |   40 ++++--
 sys/fs/puffs/puffs_vfsops.c                             |   25 ++-
 sys/fs/smbfs/smbfs_vfsops.c                             |   37 +++--
 sys/kern/vfs_mount.c                                    |  101 ++++++++-------
 sys/kern/vfs_subr.c                                     |    6 +-
 sys/nfs/nfs_subs.c                                      |   54 ++++---
 sys/nfs/nfs_vfsops.c                                    |   20 +-
 sys/sys/mount.h                                         |    5 +-
 sys/sys/param.h                                         |    4 +-
 sys/ufs/ext2fs/ext2fs_vfsops.c                          |   47 ++++---
 sys/ufs/ffs/ffs_snapshot.c                              |   72 +++++++---
 sys/ufs/ffs/ffs_vfsops.c                                |   94 ++++++++------
 sys/ufs/lfs/ulfs_quota1.c                               |   10 +-
 sys/ufs/ufs/ufs_quota1.c                                |   10 +-
 16 files changed, 343 insertions(+), 246 deletions(-)

diffs (truncated from 1147 to 300 lines):

diff -r 69384f40e961 -r 3ea918660cd5 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c   Sat May 24 15:20:32 2014 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c   Sat May 24 16:34:03 2014 +0000
@@ -147,6 +147,20 @@
        mntopts
 };
 
+static bool
+zfs_sync_selector(void *cl, struct vnode *vp)
+{
+       znode_t *zp;
+
+       /*
+        * Skip the vnode/inode if inaccessible, or if the
+        * atime is clean.
+        */
+       zp = VTOZ(vp);
+       return zp != NULL && vp->v_type != VNON && zp->z_atime_dirty != 0
+           && !zp->z_unlinked;
+}
+
 /*ARGSUSED*/
 int
 zfs_sync(vfs_t *vfsp, int flag, cred_t *cr)
@@ -174,22 +188,14 @@
         * BSD VFS, so we do it in batch here.
         */
        vfs_vnode_iterator_init(vfsp, &marker);
-       while (vfs_vnode_iterator_next(marker, &vp)) {
+       while ((vp = vfs_vnode_iterator_next(marker, zfs_sync_selector, NULL)))
+       {
                error = vn_lock(vp, LK_EXCLUSIVE);
                if (error) {
                        vrele(vp);
                        continue;
                }
-               /*
-                * Skip the vnode/inode if inaccessible, or if the
-                * atime is clean.
-                */
                zp = VTOZ(vp);
-               if (zp == NULL || vp->v_type == VNON ||
-                  zp->z_atime_dirty == 0 || zp->z_unlinked) {
-                       vput(vp);
-                       continue;
-               }
                tx = dmu_tx_create(zfsvfs->z_os);
                dmu_tx_hold_bonus(tx, zp->z_id);
                error = dmu_tx_assign(tx, TXG_WAIT);
diff -r 69384f40e961 -r 3ea918660cd5 share/man/man9/vfssubr.9
--- a/share/man/man9/vfssubr.9  Sat May 24 15:20:32 2014 +0000
+++ b/share/man/man9/vfssubr.9  Sat May 24 16:34:03 2014 +0000
@@ -1,4 +1,4 @@
-.\"     $NetBSD: vfssubr.9,v 1.23 2014/03/18 10:21:47 hannken Exp $
+.\"     $NetBSD: vfssubr.9,v 1.24 2014/05/24 16:34:03 christos Exp $
 .\"
 .\" Copyright (c) 2003, 2005, 2006 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 18, 2014
+.Dd May 24, 2014
 .Dt VFSSUBR 9
 .Os
 .Sh NAME
@@ -100,11 +100,11 @@
 .Ft void
 .Fn vfs_resume "struct mount *mp"
 .Ft void
-.Fn vfs_vnode_iterator_init "struct mount *mp" " struct vnode_iterator **vip"
+.Fn vfs_vnode_iterator_init "struct mount *mp" "struct vnode_iterator **vip"
 .Ft void
 .Fn vfs_vnode_iterator_destroy "struct vnode_iterator *vi"
-.Ft bool
-.Fn vfs_vnode_iterator_next "struct vnode_iterator *vi" " struct vnode **vpp"
+.Ft struct vnode *
+.Fn vfs_vnode_iterator_next "struct vnode_iterator *vi" "bool (*selector)(void *context, struct vnode *vpp)" "void *context"
 .Sh DESCRIPTION
 The high-level functions described in this page are the interface to
 the kernel file system interface (VFS).
@@ -243,20 +243,26 @@
 .It Fn vfs_vnode_iterator_destroy "vi"
 Free all resources associated with an iterator
 .Fa vi .
-.It Fn vfs_vnode_iterator_next "vi" "vpp"
+.It Fn vfs_vnode_iterator_next "vi" "selector" "context"
 Return the next vnode from iterator
 .Fa vi .
 If the operation is successful the vnode has a reference added to it
-and it is returned in
-.Fa *vpp
-and the function returns
-.Dv true .
-If the iterator is exhausted,
-.Fa *vpp
-is
-.Dv NULL
-and the function returns
-.Dv false .
+and it is returned
+If the iterator is exhausted
+the function returns
+.Dv NULL .
+If an optional
+.Fa selector
+function is provided, then this function is called with the
+.Fa context
+provided and the candidate vnode to be returned.
+If the
+.Fa selector
+returns
+.Dv false ,
+then the vnode is skipped; if it returns
+.Dv true ,
+the vnode is referenced and then returned.
 .El
 .Sh CODE REFERENCES
 The vfs interface functions are implemented within the files
diff -r 69384f40e961 -r 3ea918660cd5 sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c   Sat May 24 15:20:32 2014 +0000
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c   Sat May 24 16:34:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vfsops.c,v 1.107 2014/04/16 18:55:18 maxv Exp $        */
+/*     $NetBSD: msdosfs_vfsops.c,v 1.108 2014/05/24 16:34:03 christos Exp $    */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.107 2014/04/16 18:55:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.108 2014/05/24 16:34:03 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -943,14 +943,34 @@
        return (0);
 }
 
+struct msdosfs_sync_ctx {
+       int waitfor;
+};
+
+static bool
+msdosfs_sync_selector(void *cl, struct vnode *vp)
+{
+       struct msdosfs_sync_ctx *c = cl;
+       struct denode *dep;
+
+       dep = VTODE(vp);
+       if (c->waitfor == MNT_LAZY || vp->v_type == VNON ||
+           dep == NULL || (((dep->de_flag &
+           (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) &&
+            (LIST_EMPTY(&vp->v_dirtyblkhd) &&
+             UVM_OBJ_IS_CLEAN(&vp->v_uobj))))
+               return false;
+       return true;
+}
+
 int
 msdosfs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
 {
        struct vnode *vp;
        struct vnode_iterator *marker;
-       struct denode *dep;
        struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
        int error, allerror = 0;
+       struct msdosfs_sync_ctx ctx;
 
        /*
         * If we ever switch to not updating all of the FATs all the time,
@@ -968,21 +988,15 @@
         * Write back each (modified) denode.
         */
        vfs_vnode_iterator_init(mp, &marker);
-       while (vfs_vnode_iterator_next(marker, &vp)) {
+       ctx.waitfor = waitfor;
+       while ((vp = vfs_vnode_iterator_next(marker, msdosfs_sync_selector,
+           &ctx)))
+       {
                error = vn_lock(vp, LK_EXCLUSIVE);
                if (error) {
                        vrele(vp);
                        continue;
                }
-               dep = VTODE(vp);
-               if (waitfor == MNT_LAZY || vp->v_type == VNON ||
-                   dep == NULL || (((dep->de_flag &
-                   (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) &&
-                    (LIST_EMPTY(&vp->v_dirtyblkhd) &&
-                     UVM_OBJ_IS_CLEAN(&vp->v_uobj)))) {
-                       vput(vp);
-                       continue;
-               }
                if ((error = VOP_FSYNC(vp, cred,
                    waitfor == MNT_WAIT ? FSYNC_WAIT : 0, 0, 0)) != 0)
                        allerror = error;
diff -r 69384f40e961 -r 3ea918660cd5 sys/fs/puffs/puffs_vfsops.c
--- a/sys/fs/puffs/puffs_vfsops.c       Sat May 24 15:20:32 2014 +0000
+++ b/sys/fs/puffs/puffs_vfsops.c       Sat May 24 16:34:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: puffs_vfsops.c,v 1.110 2014/04/16 18:55:18 maxv Exp $  */
+/*     $NetBSD: puffs_vfsops.c,v 1.111 2014/05/24 16:34:03 christos Exp $      */
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.110 2014/04/16 18:55:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.111 2014/05/24 16:34:03 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -510,6 +510,18 @@
        return error;
 }
 
+static bool
+pageflush_selector(void *cl, struct vnode *vp)
+{
+       bool rv;
+
+       mutex_enter(vp->v_interlock);
+       rv = vp->v_type == VREG && !UVM_OBJ_IS_CLEAN(&vp->v_uobj);
+       mutex_exit(vp->v_interlock);
+
+       return rv;
+}
+
 static int
 pageflush(struct mount *mp, kauth_cred_t cred, int waitfor)
 {
@@ -528,7 +540,9 @@
         * all the nodes it knows to exist.
         */
        vfs_vnode_iterator_init(mp, &marker);
-       while (vfs_vnode_iterator_next(marker, &vp)) {
+       while ((vp = vfs_vnode_iterator_next(marker, pageflush_selector,
+           NULL)))
+       {
                /*
                 * Here we try to get a reference to the vnode and to
                 * lock it.  This is mostly cargo-culted, but I will
@@ -550,11 +564,6 @@
                        continue;
                }
                pn = VPTOPP(vp);
-               if (vp->v_type != VREG || UVM_OBJ_IS_CLEAN(&vp->v_uobj)) {
-                       vput(vp);
-                       continue;
-               }
-
                /* hmm.. is the FAF thing entirely sensible? */
                if (waitfor == MNT_LAZY) {
                        mutex_enter(vp->v_interlock);
diff -r 69384f40e961 -r 3ea918660cd5 sys/fs/smbfs/smbfs_vfsops.c
--- a/sys/fs/smbfs/smbfs_vfsops.c       Sat May 24 15:20:32 2014 +0000
+++ b/sys/fs/smbfs/smbfs_vfsops.c       Sat May 24 16:34:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smbfs_vfsops.c,v 1.100 2014/04/16 18:55:18 maxv Exp $  */
+/*     $NetBSD: smbfs_vfsops.c,v 1.101 2014/05/24 16:34:03 christos Exp $      */
 
 /*
  * Copyright (c) 2000-2001, Boris Popov
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.100 2014/04/16 18:55:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.101 2014/05/24 16:34:03 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -400,6 +400,23 @@
        return 0;
 }
 
+static bool
+smbfs_sync_selector(void *cl, struct vnode *vp)
+{
+       struct smbnode *np;
+
+       np = VTOSMB(vp);
+       if (np == NULL)
+               return false;
+
+       if ((vp->v_type == VNON || (np->n_flag & NMODIFIED) == 0) &&
+           LIST_EMPTY(&vp->v_dirtyblkhd) &&
+            vp->v_uobj.uo_npages == 0)
+               return false;
+
+       return true;
+}
+
 /*



Home | Main Index | Thread Index | Old Index