VFS messaging/interfacing work stage 10/99:
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 17 Dec 2004 00:18:49 +0000 (00:18 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 17 Dec 2004 00:18:49 +0000 (00:18 +0000)
Start adding the journaling, range locking, and (very slightly) cache
coherency infrastructure.  Continue cleaning up the VOP operations vector.

Expand on past commits that gave each mount structure its own set of VOP
operations vectors by adding additional vector sets for journaling or
cache coherency operations.  Remove the vv_jops and vv_cops fields
from the vnode operations vector in favor of placing those vop_ops directly
in the mount structure.  Reorganize the VOP calls as a double-indirect
and add a field to the mount structure which represents the current
vnode operations set (which will change when e.g. journaling is turned on
or off).  This creates the infrastructure necessary to allow us to stack
a generic journaling implementation on top of a filesystem.

Introduce a hard range-locking API for vnodes.   This API will be used by
high level system/vfs calls in order to handle atomicy guarentees.  It is
a prerequisit for: (1) being able to break I/O's up into smaller pieces
for the vm_page list/direct-to-DMA-without-mapping goal, (2) to support
the parallel write operations on a vnode goal, (3) to support the clustered
(remote) cache coherency goal, and (4) to support massive parallelism in
dispatching operations for the upcoming threaded VFS work.

This commit represents only infrastructure and skeleton/API work.

52 files changed:
sys/conf/files
sys/emulation/linux/i386/linprocfs/linprocfs_subr.c
sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c
sys/kern/vfs_cache.c
sys/kern/vfs_init.c
sys/kern/vfs_jops.c [new file with mode: 0644]
sys/kern/vfs_journal.c [new file with mode: 0644]
sys/kern/vfs_mount.c
sys/kern/vfs_rangelock.c [new file with mode: 0644]
sys/kern/vfs_subr.c
sys/kern/vfs_sync.c
sys/kern/vfs_syscalls.c
sys/kern/vfs_vopops.c
sys/sys/mount.h
sys/sys/namecache.h
sys/sys/vfsops.h
sys/sys/vnode.h
sys/vfs/coda/coda_vnops.c
sys/vfs/fdesc/fdesc_vfsops.c
sys/vfs/fdesc/fdesc_vnops.c
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/msdosfs/msdosfs_denode.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/nfs/nfs_node.c
sys/vfs/nfs/nfs_subs.c
sys/vfs/nfs/nfs_vfsops.c
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/nullfs/null_subr.c
sys/vfs/nullfs/null_vfsops.c
sys/vfs/nullfs/null_vnops.c
sys/vfs/nwfs/nwfs_node.c
sys/vfs/nwfs/nwfs_vfsops.c
sys/vfs/portal/portal_vfsops.c
sys/vfs/portal/portal_vnops.c
sys/vfs/procfs/procfs_subr.c
sys/vfs/procfs/procfs_vfsops.c
sys/vfs/smbfs/smbfs_node.c
sys/vfs/smbfs/smbfs_vfsops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/udf/udf_vnops.c
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_vnops.c
sys/vfs/umapfs/umap_subr.c
sys/vfs/umapfs/umap_vfsops.c
sys/vfs/umapfs/umap_vnops.c
sys/vfs/union/union_subr.c
sys/vfs/union/union_vfsops.c
sys/vfs/union/union_vnops.c
sys/vm/vm_swap.c

index 397a1c6..5554fb8 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/sys/conf/files,v 1.81 2004/11/24 22:51:01 joerg Exp $
+# $DragonFly: src/sys/conf/files,v 1.82 2004/12/17 00:18:03 dillon Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -725,11 +725,13 @@ kern/vfs_cluster.c        standard
 kern/vfs_conf.c                standard
 kern/vfs_default.c     standard
 kern/vfs_init.c                standard
+kern/vfs_journal.c     standard
 kern/vfs_lookup.c      standard
 kern/vfs_nlookup.c     standard
 kern/vfs_subr.c                standard
 kern/vfs_lock.c                standard
 kern/vfs_mount.c       standard
+kern/vfs_rangelock.c   standard
 kern/vfs_sync.c                standard
 kern/vfs_syscalls.c    standard
 kern/vfs_vnops.c       standard
index 1c19c5e..7c59e79 100644 (file)
@@ -39,7 +39,7 @@
  *     @(#)procfs_subr.c       8.6 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_subr.c,v 1.3.2.4 2001/06/25 19:46:47 pirzyk Exp $
- * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v 1.14 2004/10/19 09:29:46 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v 1.15 2004/12/17 00:18:05 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -128,7 +128,7 @@ loop:
         */
        MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
 
-       error = getnewvnode(VT_PROCFS, mp, mp->mnt_vn_ops, vpp, 0, 0);
+       error = getnewvnode(VT_PROCFS, mp, vpp, 0, 0);
        if (error) {
                FREE(pfs, M_TEMP);
                goto out;
index 83338d1..ad9d42e 100644 (file)
@@ -39,7 +39,7 @@
  *     @(#)procfs_vfsops.c     8.7 (Berkeley) 5/10/95
  *
  * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_vfsops.c,v 1.2.2.3 2001/10/15 20:42:01 des Exp $
- * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c,v 1.7 2004/09/30 18:59:41 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c,v 1.8 2004/12/17 00:18:05 dillon Exp $
  */
 
 /*
@@ -92,7 +92,7 @@ linprocfs_mount(mp, path, data, td)
        mp->mnt_data = 0;
        vfs_getnewfsid(mp);
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, linprocfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, linprocfs_vnodeop_entries);
 
        (void) copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN, &size);
        bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
index b748d7f..6d18b94 100644 (file)
@@ -67,7 +67,7 @@
  *
  *     @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
  * $FreeBSD: src/sys/kern/vfs_cache.c,v 1.42.2.6 2001/10/05 20:07:03 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_cache.c,v 1.45 2004/12/08 18:53:27 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_cache.c,v 1.46 2004/12/17 00:18:07 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -833,7 +833,7 @@ force:
                /*
                 * Get the parent directory and resolve its ncp.
                 */
-               error = vop_nlookupdotdot(dvp->v_ops, dvp, &pvp, cred);
+               error = vop_nlookupdotdot(*dvp->v_ops, dvp, &pvp, cred);
                if (error) {
                        printf("lookupdotdot failed %d %p\n", error, pvp);
                        break;
@@ -1393,7 +1393,7 @@ restart:
         */
        KKASSERT((ncp->nc_flag & NCF_MOUNTPT) == 0);
        ncp->nc_error = VOP_NRESOLVE(ncp, cred);
-       /*vop_nresolve(ncp->nc_parent->nc_vp->v_ops, ncp, cred);*/
+       /*vop_nresolve(*ncp->nc_parent->nc_vp->v_ops, ncp, cred);*/
        if (ncp->nc_error == EAGAIN) {
                printf("[diagnostic] cache_resolve: EAGAIN ncp %p %*.*s\n",
                        ncp, ncp->nc_nlen, ncp->nc_nlen, ncp->nc_name);
index f89f47c..e307f91 100644 (file)
@@ -70,7 +70,7 @@
  *
  *     @(#)vfs_init.c  8.3 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/kern/vfs_init.c,v 1.59 2002/04/30 18:44:32 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_init.c,v 1.7 2004/10/12 19:20:46 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_init.c,v 1.8 2004/12/17 00:18:07 dillon Exp $
  */
 /*
  * Manage vnode VOP operations vectors
@@ -109,7 +109,7 @@ vfs_add_vnodeops_sysinit(const void *data)
 {
        const struct vnodeopv_desc *vdesc = data;
 
-       vfs_add_vnodeops(vdesc->opv_desc_vector, vdesc->opv_desc_ops);
+       vfs_add_vnodeops(NULL, vdesc->opv_desc_vector, vdesc->opv_desc_ops);
 }
 
 /*
@@ -124,7 +124,8 @@ vfs_rm_vnodeops_sysinit(const void *data)
 }
 
 void
-vfs_add_vnodeops(struct vop_ops **vops_pp, struct vnodeopv_entry_desc *descs)
+vfs_add_vnodeops(struct mount *mp, struct vop_ops **vops_pp,
+               struct vnodeopv_entry_desc *descs)
 {
        struct vnodeopv_node *node;
        struct vop_ops *ops;
@@ -137,9 +138,18 @@ vfs_add_vnodeops(struct vop_ops **vops_pp, struct vnodeopv_entry_desc *descs)
        }
        node->ops = ops;
        node->descs = descs;
+       ops->vv_mount = mp;
        ++ops->vv_refs;
        TAILQ_INSERT_TAIL(&vnodeopv_list, node, entry);
        vfs_recalc_vnodeops();
+       if (mp) {
+               if (mp->mnt_vn_coherency_ops)
+                       mp->mnt_vn_use_ops = mp->mnt_vn_coherency_ops;
+               else if (mp->mnt_vn_journal_ops)
+                       mp->mnt_vn_use_ops = mp->mnt_vn_journal_ops;
+               else
+                       mp->mnt_vn_use_ops = mp->mnt_vn_norm_ops;
+       }
 }
 
 void
@@ -147,6 +157,7 @@ vfs_rm_vnodeops(struct vop_ops **vops_pp)
 {
        struct vop_ops *ops = *vops_pp;
        struct vnodeopv_node *node;
+       struct mount *mp;
 
        if (ops == NULL)
                return;
@@ -164,6 +175,14 @@ vfs_rm_vnodeops(struct vop_ops **vops_pp)
        KKASSERT(ops != NULL && ops->vv_refs > 0);
        if (--ops->vv_refs == 0) {
                *vops_pp = NULL;
+               if ((mp = ops->vv_mount) != NULL) {
+                       if (mp->mnt_vn_coherency_ops)
+                               mp->mnt_vn_use_ops = mp->mnt_vn_coherency_ops;
+                       else if (mp->mnt_vn_journal_ops)
+                               mp->mnt_vn_use_ops = mp->mnt_vn_journal_ops;
+                       else
+                               mp->mnt_vn_use_ops = mp->mnt_vn_norm_ops;
+               }
                free(ops, M_VNODEOP);
        }
        vfs_recalc_vnodeops();
diff --git a/sys/kern/vfs_jops.c b/sys/kern/vfs_jops.c
new file mode 100644 (file)
index 0000000..be40a8f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/kern/vfs_jops.c,v 1.1 2004/12/17 00:18:07 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/unistd.h>
+#include <sys/vnode.h>
+#include <sys/poll.h>
+
+#include <machine/limits.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <vm/vnode_pager.h>
+
+static struct vnodeopv_entry_desc journal_vnodeop_entries[] = {
+       { &vop_default_desc,            vop_journal_operate_ap },
+       { NULL, NULL }
+};
+
+int
+journal_attach(struct mount *mp)
+{
+       vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries);
+       return(0);
+}
+
+void
+journal_detach(struct mount *mp)
+{
+       if (mp->mnt_vn_journal_ops)
+               vfs_rm_vnodeops(&mp->mnt_vn_journal_ops);
+}
+
diff --git a/sys/kern/vfs_journal.c b/sys/kern/vfs_journal.c
new file mode 100644 (file)
index 0000000..3fc0b47
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/kern/vfs_journal.c,v 1.1 2004/12/17 00:18:07 dillon Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/unistd.h>
+#include <sys/vnode.h>
+#include <sys/poll.h>
+
+#include <machine/limits.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <vm/vnode_pager.h>
+
+static struct vnodeopv_entry_desc journal_vnodeop_entries[] = {
+       { &vop_default_desc,            vop_journal_operate_ap },
+       { NULL, NULL }
+};
+
+int
+journal_attach(struct mount *mp)
+{
+       vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries);
+       return(0);
+}
+
+void
+journal_detach(struct mount *mp)
+{
+       if (mp->mnt_vn_journal_ops)
+               vfs_rm_vnodeops(&mp->mnt_vn_journal_ops);
+}
+
index 34a22f1..08c8fb6 100644 (file)
@@ -67,7 +67,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/vfs_mount.c,v 1.2 2004/10/19 05:55:34 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_mount.c,v 1.3 2004/12/17 00:18:07 dillon Exp $
  */
 
 /*
@@ -128,15 +128,54 @@ vfs_mount_init(void)
  * vx_unlock() the vnode.
  */
 int
-getnewvnode(enum vtagtype tag, struct mount *mp, struct vop_ops *ops,
+getnewvnode(enum vtagtype tag, struct mount *mp,
+               struct vnode **vpp, int lktimeout, int lkflags)
+{
+       struct vnode *vp;
+
+       KKASSERT(mp != NULL);
+
+       vp = allocvnode(lktimeout, lkflags);
+       vp->v_tag = tag;
+       vp->v_data = NULL;
+
+       /*
+        * By default the vnode is assigned the mount point's normal
+        * operations vector.
+        */
+       vp->v_ops = &mp->mnt_vn_use_ops;
+
+       /*
+        * Placing the vnode on the mount point's queue makes it visible.
+        * VNON prevents it from being messed with, however.
+        */
+       insmntque(vp, mp);
+       vfs_object_create(vp, curthread);
+
+       /*
+        * A VX locked & refd vnode is returned.
+        */
+       *vpp = vp;
+       return (0);
+}
+
+/*
+ * This function creates vnodes with special operations vectors.  The
+ * mount point is optional.
+ *
+ * This routine is being phased out.
+ */
+int
+getspecialvnode(enum vtagtype tag, struct mount *mp,
+               struct vop_ops **ops_pp,
                struct vnode **vpp, int lktimeout, int lkflags)
 {
        struct vnode *vp;
 
        vp = allocvnode(lktimeout, lkflags);
        vp->v_tag = tag;
-       vp->v_ops = ops;
        vp->v_data = NULL;
+       vp->v_ops = ops_pp;
 
        /*
         * Placing the vnode on the mount point's queue makes it visible.
@@ -770,7 +809,7 @@ vflush_scan(struct mount *mp, struct vnode *vp, void *data)
                        vgone(vp);
                } else {
                        vclean(vp, 0, info->td);
-                       vp->v_ops = spec_vnode_vops;
+                       vp->v_ops = &spec_vnode_vops;
                        insmntque(vp, NULL);
                }
                return(0);
diff --git a/sys/kern/vfs_rangelock.c b/sys/kern/vfs_rangelock.c
new file mode 100644 (file)
index 0000000..b6b61a7
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/kern/vfs_rangelock.c,v 1.1 2004/12/17 00:18:07 dillon Exp $
+ */
+/*
+ * This module implements hard range locks for files and directories.  It is
+ * not to be confused with the UNIX advisory lock mechanism.  This module
+ * will allow the kernel and VFS to break large I/O requests into smaller
+ * pieces without losing atomicy guarentees and, eventually, this module will
+ * be responsible for providing hooks for remote cache coherency protocols
+ * as well.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/unistd.h>
+#include <sys/vnode.h>
+#include <sys/poll.h>
+
+#include <machine/limits.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <vm/vnode_pager.h>
+
+static void vrange_lock_overlapped(struct vnode *vp, 
+                       struct vrangelock *vr, struct vrangelock *scan);
+static int vrange_lock_conflicted(struct vnode *vp, struct vrangelock *vr);
+
+/*
+ * Lock a range within a vnode.
+ *
+ * The lock list is sorted by vr_offset.
+ */
+void
+vrange_lock(struct vnode *vp, struct vrangelock *vr)
+{
+    struct vrangelock *scan;
+    off_t eoff;
+
+    eoff = vr->vr_offset + vr->vr_length;
+
+    KKASSERT((vr->vr_flags & RNGL_ONLIST) == 0);
+    vr->vr_flags |= RNGL_ONLIST;
+
+    TAILQ_FOREACH(scan, &vp->v_range.vh_list, vr_node) {
+       /*
+        * If the new element is entirely in front of the scan element
+        * we are done.  If it is entirely beyond the scan element we
+        * loop.  Otherwise an overlap has occured.
+        */
+       if (eoff <= scan->vr_offset) {
+           TAILQ_INSERT_BEFORE(scan, vr, vr_node);
+           return;
+       }
+       if (vr->vr_offset >= scan->vr_offset + scan->vr_length)
+           continue;
+       vrange_lock_overlapped(vp, vr, scan);
+    }
+    TAILQ_INSERT_TAIL(&vp->v_range.vh_list, vr, vr_node);
+}
+
+/*
+ * An overlap occured.  The request is still inserted sorted based on
+ * vr_offset but we must also scan the conflict space and block while
+ * conflicts exist.
+ */
+static void
+vrange_lock_overlapped(struct vnode *vp, 
+                       struct vrangelock *vr, struct vrangelock *scan)
+{
+    int conflicted = 0;
+    int inserted = 0;
+    int warned = 0;
+    off_t eoff;
+
+    eoff = vr->vr_offset + vr->vr_length;
+
+    while (scan->vr_offset < eoff) {
+       if ((vr->vr_flags & scan->vr_flags & RNGL_SHARED) == 0) {
+           scan->vr_flags |= RNGL_CHECK;
+           vr->vr_flags |= RNGL_WAITING;
+           conflicted = 1;
+       }
+       if (inserted == 0 && vr->vr_offset < scan->vr_offset) {
+           TAILQ_INSERT_BEFORE(scan, vr, vr_node);
+           inserted = 1;
+       }
+       if ((scan = TAILQ_NEXT(scan, vr_node)) == NULL) {
+           if (inserted == 0)
+               TAILQ_INSERT_TAIL(&vp->v_range.vh_list, vr, vr_node);
+           break;
+       }
+    }
+
+    /*
+     * sleep until the conflict has been resolved.
+     */
+    while (conflicted) {
+       if (tsleep(&vp->v_range.vh_list, 0, "vrnglk", hz * 3) == EWOULDBLOCK) {
+           if (warned == 0)
+               printf("warning: conflicted lock vp %p %lld,%lld blocked\n",
+                   vp, vr->vr_offset, vr->vr_length);
+           warned = 1;
+       }
+       conflicted = vrange_lock_conflicted(vp, vr);
+    }
+    if (warned) {
+       printf("waring: conflicted lock vp %p %lld,%lld unblocked\n",
+           vp, vr->vr_offset, vr->vr_length);
+    }
+}
+
+/*
+ * Check for conflicts by scanning both forwards and backwards from the
+ * node in question.  The list is sorted by vr_offset but ending offsets
+ * may vary.  Because of this, the reverse scan cannot stop early.
+ *
+ * Return 0 on success, 1 if the lock is still conflicted.  We do not
+ * check elements that are waiting as that might result in a deadlock.
+ * We can stop the moment we hit a conflict.
+ */
+static int
+vrange_lock_conflicted(struct vnode *vp, struct vrangelock *vr)
+{
+    struct vrangelock *scan;
+    off_t eoff;
+
+    eoff = vr->vr_offset + vr->vr_length;
+
+    KKASSERT(vr->vr_flags & RNGL_WAITING);
+    scan = vr;
+    while ((scan = TAILQ_PREV(scan, vrangelock_list, vr_node)) != NULL) {
+       if (scan->vr_flags & RNGL_WAITING)
+               continue;
+       if (scan->vr_offset + scan->vr_length > vr->vr_offset) {
+           if ((vr->vr_flags & scan->vr_flags & RNGL_SHARED) == 0) {
+               scan->vr_flags |= RNGL_CHECK;
+               return(1);
+           }
+       }
+    }
+    scan = vr;
+    while ((scan = TAILQ_NEXT(scan, vr_node)) != NULL) {
+       if (eoff <= scan->vr_offset)
+           break;
+       if (scan->vr_flags & RNGL_WAITING)
+           continue;
+       if ((vr->vr_flags & scan->vr_flags & RNGL_SHARED) == 0) {
+           scan->vr_flags |= RNGL_CHECK;
+           return(1);
+       }
+    }
+    vr->vr_flags &= ~RNGL_WAITING;
+    return(0);
+}
+
+void
+vrange_unlock(struct vnode *vp, struct vrangelock *vr)
+{
+    KKASSERT((vr->vr_flags & RNGL_ONLIST) != 0);
+    vr->vr_flags &= ~RNGL_ONLIST;
+    TAILQ_REMOVE(&vp->v_range.vh_list, vr, vr_node);
+    if (vr->vr_flags & RNGL_CHECK) {
+       vr->vr_flags &= ~RNGL_CHECK;
+       wakeup(&vp->v_range.vh_list);
+    }
+}
+
index 573df3b..c20be2a 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_subr.c  8.31 (Berkeley) 5/26/95
  * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_subr.c,v 1.49 2004/12/14 18:46:08 hsu Exp $
+ * $DragonFly: src/sys/kern/vfs_subr.c,v 1.50 2004/12/17 00:18:07 dillon Exp $
  */
 
 /*
@@ -737,7 +737,7 @@ bdevvp(dev_t dev, struct vnode **vpp)
                *vpp = NULLVP;
                return (ENXIO);
        }
-       error = getnewvnode(VT_NON, NULL, spec_vnode_vops, &nvp, 0, 0);
+       error = getspecialvnode(VT_NON, NULL, &spec_vnode_vops, &nvp, 0, 0);
        if (error) {
                *vpp = NULLVP;
                return (error);
@@ -871,7 +871,7 @@ vclean(struct vnode *vp, int flags, struct thread *td)
        /*
         * Done with purge, notify sleepers of the grim news.
         */
-       vp->v_ops = dead_vnode_vops;
+       vp->v_ops = &dead_vnode_vops;
        vn_pollgone(vp);
        vp->v_tag = VT_NON;
 }
index cae909b..067a8f3 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_subr.c  8.31 (Berkeley) 5/26/95
  * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_sync.c,v 1.1 2004/10/12 19:20:46 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_sync.c,v 1.2 2004/12/17 00:18:07 dillon Exp $
  */
 
 /*
@@ -342,7 +342,7 @@ vfs_allocate_syncvnode(struct mount *mp)
        int error;
 
        /* Allocate a new vnode */
-       error = getnewvnode(VT_VFS, mp, sync_vnode_vops, &vp, 0, 0);
+       error = getspecialvnode(VT_VFS, mp, &sync_vnode_vops, &vp, 0, 0);
        if (error) {
                mp->mnt_syncer = NULL;
                return (error);
index ea5883d..5dee402 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.48 2004/11/24 08:37:16 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.49 2004/12/17 00:18:07 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -373,7 +373,9 @@ update:
                if ((error = VFS_START(mp, 0, td)) != 0)
                        vrele(vp);
        } else {
-               vfs_rm_vnodeops(&mp->mnt_vn_ops);
+               vfs_rm_vnodeops(&mp->mnt_vn_coherency_ops);
+               vfs_rm_vnodeops(&mp->mnt_vn_journal_ops);
+               vfs_rm_vnodeops(&mp->mnt_vn_norm_ops);
                vfs_rm_vnodeops(&mp->mnt_vn_spec_ops);
                vfs_rm_vnodeops(&mp->mnt_vn_fifo_ops);
                vp->v_flag &= ~VMOUNT;
@@ -562,7 +564,9 @@ dounmount(struct mount *mp, int flags, struct thread *td)
         * Remove any installed vnode ops here so the individual VFSs don't
         * have to.
         */
-       vfs_rm_vnodeops(&mp->mnt_vn_ops);
+       vfs_rm_vnodeops(&mp->mnt_vn_coherency_ops);
+       vfs_rm_vnodeops(&mp->mnt_vn_journal_ops);
+       vfs_rm_vnodeops(&mp->mnt_vn_norm_ops);
        vfs_rm_vnodeops(&mp->mnt_vn_spec_ops);
        vfs_rm_vnodeops(&mp->mnt_vn_fifo_ops);
 
index 0848a06..70537f9 100644 (file)
@@ -32,7 +32,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.10 2004/11/12 00:09:24 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.11 2004/12/17 00:18:07 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -293,24 +293,8 @@ VNODEOP_DESC_INIT_NCP_CRED(nremove);
 VNODEOP_DESC_INIT_NCP_CRED(nrmdir);
 VNODEOP_DESC_INIT_NCP2_CRED(nrename);
 
-/*
- * The DO_OPS macro basicallys calls ops->blah(&ap) but is also responsible
- * for checking vv_flags and executing additional hook functions.
- *
- * NOTE: vop_vnoperate_ap() rolls its own DO_OPS equivalent.
- */
-#define DO_OPS(ops, error, ap, vop_field)                              \
-       if (ops->vv_flags & VVF_HOOK_MASK) {                            \
-               if (ops->vv_flags & VVF_JOURNAL_HOOK)                   \
-                       error = ops->vv_jops->vop_field(ap);            \
-               else                                                    \
-                       error = 0;                                      \
-               if (error == 0)                                         \
-                       error = ops->vop_field(ap);                     \
-       } else {                                                        \
-               error = ops->vop_field(ap);                             \
-       }                                                               \
-
+#define DO_OPS(ops, error, ap, vop_field)      \
+       error = ops->vop_field(ap);
 
 /************************************************************************
  *             PRIMARY HIGH LEVEL VNODE OPERATIONS CALLS               *
@@ -1496,16 +1480,44 @@ vop_vnoperate_ap(struct vop_generic_args *ap)
        int error;
 
        ops = ap->a_ops;
-       if (ops->vv_flags & VVF_HOOK_MASK) {
-               if (ops->vv_flags & VVF_JOURNAL_HOOK)
-                       error = VOCALL(ops->vv_jops, ap);
-               else
-                       error = 0;
-               if (error == 0)
-                       error = VOCALL(ops, ap);
-       } else {
-               error = VOCALL(ops, ap);
-       }
+       error = VOCALL(ops, ap);
+
+       return (error);
+}
+
+/*
+ * This routine is called by the cache coherency layer to execute the actual
+ * VFS operation.  If a journaling layer is present we call though it, else
+ * we call the native VOP functions.
+ */
+int
+vop_cache_operate_ap(struct vop_generic_args *ap)
+{
+       struct vop_ops *ops;
+       int error;
+
+       ops = ap->a_ops;
+       if (ops->vv_mount->mnt_vn_journal_ops)
+               error = VOCALL(ops->vv_mount->mnt_vn_journal_ops, ap);
+       else
+               error = VOCALL(ops->vv_mount->mnt_vn_norm_ops, ap);
+       return (error);
+}
+
+
+/*
+ * This routine is called by the journaling layer to execute the actual
+ * VFS operation.
+ */
+int
+vop_journal_operate_ap(struct vop_generic_args *ap)
+{
+       struct vop_ops *ops;
+       int error;
+
+       ops = ap->a_ops;
+       error = VOCALL(ops->vv_mount->mnt_vn_norm_ops, ap);
+
        return (error);
 }
 
index 5b0f375..a9eb54c 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)mount.h     8.21 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/sys/mount.h,v 1.89.2.7 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/sys/mount.h,v 1.14 2004/11/12 00:09:27 dillon Exp $
+ * $DragonFly: src/sys/sys/mount.h,v 1.15 2004/12/17 00:18:09 dillon Exp $
  */
 
 #ifndef _SYS_MOUNT_H_
@@ -146,7 +146,18 @@ struct mount {
        u_int           mnt_iosize_max;         /* max IO request size */
        struct vnodelst mnt_reservedvnlist;     /* (future) dirty vnode list */
        int             mnt_nvnodelistsize;     /* # of vnodes on this mount */
-       struct vop_ops  *mnt_vn_ops;            /* for use by the VFS */
+
+       /*
+        * ops vectors have a fixed stacking order.  All primary calls run
+        * through mnt_vn_ops.  This field is typically assigned to 
+        * mnt_vn_norm_ops.  If journaling has been enabled this field is
+        * usually assigned to mnt_vn_journal_ops.
+        */
+       struct vop_ops  *mnt_vn_use_ops;        /* current ops set */
+
+       struct vop_ops  *mnt_vn_coherency_ops;  /* cache coherency ops */
+       struct vop_ops  *mnt_vn_journal_ops;    /* journaling ops */
+       struct vop_ops  *mnt_vn_norm_ops;       /* for use by the VFS */
        struct vop_ops  *mnt_vn_spec_ops;       /* for use by the VFS */
        struct vop_ops  *mnt_vn_fifo_ops;       /* for use by the VFS */
        struct namecache *mnt_ncp;              /* NCF_MNTPT ncp */
@@ -517,6 +528,9 @@ int fhopen (const struct fhandle *, int);
 int    fhstat (const struct fhandle *, struct stat *);
 int    fhstatfs (const struct fhandle *, struct statfs *);
 
+int    journal_attach(struct mount *mp);
+int    journal_detach(struct mount *mp);
+
 /* C library stuff */
 void   endvfsent (void);
 struct ovfsconf *getvfsbyname (const char *);
index 504d0f8..c1d2339 100644 (file)
@@ -62,7 +62,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/namecache.h,v 1.16 2004/11/18 20:04:26 dillon Exp $
+ * $DragonFly: src/sys/sys/namecache.h,v 1.17 2004/12/17 00:18:09 dillon Exp $
  */
 
 #ifndef _SYS_NAMECACHE_H_
@@ -94,7 +94,7 @@ TAILQ_HEAD(namecache_list, namecache);
  * into lower layer VOP calls.
  *
  * Many new API VOP operations do not pass vnodes.  In these cases the
- * operations vector is typically obtained via nc_mount->mnt_vn_ops.
+ * operations vector is typically obtained via nc_mount->mnt_vn_use_ops.
  */
 struct namecache {
     LIST_ENTRY(namecache) nc_hash;     /* hash chain (nc_parent,name) */
index 5f16a22..efe5de4 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/vfsops.h,v 1.9 2004/11/12 00:09:27 dillon Exp $
+ * $DragonFly: src/sys/sys/vfsops.h,v 1.10 2004/12/17 00:18:09 dillon Exp $
  */
 
 /*
@@ -570,16 +570,13 @@ struct vop_nrename_args {
  */
 struct vop_ops {
        struct vop_ops  *vv_new;        /* vfs_recalc_vnodeops() only */
-       struct mount    *vv_mount;      /* may be NULL */
+       struct mount    *vv_mount;
        int             vv_refs;
        int             vv_flags;       /* see VVF_* flags below */
 
-       struct vop_ops  *vv_jops;       /* VVF_JOURNAL_HOOK */
-       struct vop_ops  *vv_cops;       /* VVF_CCOHERENCY_HOOK */
+       void            *vv_unused1;
+       void            *vv_unused2;
 
-       /* XXX Journaling control */
-       /* XXX Cache Coherency functions (local/remote/clustered) */
-       /* XXX Other */
        int             vv_reserved[62]; /* (temporary) reduce recompile pain */
 
 #define vop_ops_first_field    vop_default
@@ -651,8 +648,8 @@ struct vop_ops {
 #define vop_ops_last_field     vop_nrename
 };
 
-#define VVF_JOURNAL_HOOK       0x0001          /* FUTURE */
-#define VVF_CCOHERENCY_HOOK    0x0002          /* FUTURE */
+#define VVF_JOURNAL_LAYER      0x0001
+#define VVF_COHERENCY_LAYER    0x0002
 #define VVF_UNUSED_04          0x0004
 #define VVF_UNUSED_08          0x0008
 #define VVF_NOATIME            0x0010          /* FUTURE */
@@ -660,8 +657,6 @@ struct vop_ops {
 #define VVF_NOCLUSTER          0x0040          /* FUTURE */
 #define VVF_SUIDDIR            0x0080          /* FUTURE */
 
-#define VVF_HOOK_MASK          (VVF_JOURNAL_HOOK|VVF_CCOHERENCY_HOOK)
-
 /*
  * vop_vfsset() operations
  */
@@ -887,6 +882,8 @@ int vop_nrename(struct vop_ops *ops, struct namecache *fncp,
  * filesystem.  When a filesystem chains a vop_ops it just uses VOCALLs.
  */
 int vop_vnoperate_ap(struct vop_generic_args *ap);
+int vop_cache_operate_ap(struct vop_generic_args *ap);
+int vop_journal_operate_ap(struct vop_generic_args *ap);
 int vop_islocked_ap(struct vop_islocked_args *ap);
 int vop_lookup_ap(struct vop_lookup_args *ap);
 int vop_create_ap(struct vop_create_args *ap);
@@ -1028,85 +1025,85 @@ extern struct vnodeop_desc vop_nrename_desc;
  * vop_*() call.
  */
 #define VOP_ISLOCKED(vp, td)                           \
-       vop_islocked((vp)->v_ops, vp, td)
+       vop_islocked(*(vp)->v_ops, vp, td)
 #define VOP_OPEN(vp, mode, cred, fp, td)               \
-       vop_open((vp)->v_ops, vp, mode, cred, fp, td)
+       vop_open(*(vp)->v_ops, vp, mode, cred, fp, td)
 #define VOP_CLOSE(vp, fflag, td)                       \
-       vop_close((vp)->v_ops, vp, fflag, td)
+       vop_close(*(vp)->v_ops, vp, fflag, td)
 #define VOP_ACCESS(vp, mode, cred, td)                 \
-       vop_access((vp)->v_ops, vp, mode, cred, td)
+       vop_access(*(vp)->v_ops, vp, mode, cred, td)
 #define VOP_GETATTR(vp, vap, td)                       \
-       vop_getattr((vp)->v_ops, vp, vap, td)
+       vop_getattr(*(vp)->v_ops, vp, vap, td)
 #define VOP_SETATTR(vp, vap, cred, td)                 \
-       vop_setattr((vp)->v_ops, vp, vap, cred, td)
+       vop_setattr(*(vp)->v_ops, vp, vap, cred, td)
 #define VOP_READ(vp, uio, ioflag, cred)                        \
-       vop_read((vp)->v_ops, vp, uio, ioflag, cred)
+       vop_read(*(vp)->v_ops, vp, uio, ioflag, cred)
 #define VOP_WRITE(vp, uio, ioflag, cred)               \
-       vop_write((vp)->v_ops, vp, uio, ioflag, cred)
+       vop_write(*(vp)->v_ops, vp, uio, ioflag, cred)
 #define VOP_LEASE(vp, td, cred, flag)                  \
-       vop_lease((vp)->v_ops, vp, td, cred, flag)
+       vop_lease(*(vp)->v_ops, vp, td, cred, flag)
 #define VOP_IOCTL(vp, command, data, fflag, cred, td)  \
-       vop_ioctl((vp)->v_ops, vp, command, data, fflag, cred, td)
+       vop_ioctl(*(vp)->v_ops, vp, command, data, fflag, cred, td)
 #define VOP_POLL(vp, events, cred, td)                 \
-       vop_poll((vp)->v_ops, vp, events, cred, td)
+       vop_poll(*(vp)->v_ops, vp, events, cred, td)
 #define VOP_KQFILTER(vp, kn)                           \
-       vop_kqfilter((vp)->v_ops, vp, kn)
+       vop_kqfilter(*(vp)->v_ops, vp, kn)
 #define VOP_REVOKE(vp, flags)                          \
-       vop_revoke((vp)->v_ops, vp, flags)
+       vop_revoke(*(vp)->v_ops, vp, flags)
 #define VOP_MMAP(vp, fflags, cred, td)                 \
-       vop_mmap((vp)->v_ops, vp, fflags, cred, td)
+       vop_mmap(*(vp)->v_ops, vp, fflags, cred, td)
 #define VOP_FSYNC(vp, waitfor, td)                     \
-       vop_fsync((vp)->v_ops, vp, waitfor, td)
+       vop_fsync(*(vp)->v_ops, vp, waitfor, td)
 #define VOP_READDIR(vp, uio, cred, eofflag, ncookies, cookies)         \
-       vop_readdir((vp)->v_ops, vp, uio, cred, eofflag, ncookies, cookies)
+       vop_readdir(*(vp)->v_ops, vp, uio, cred, eofflag, ncookies, cookies)
 #define VOP_READLINK(vp, uio, cred)                    \
-       vop_readlink((vp)->v_ops, vp, uio, cred)
+       vop_readlink(*(vp)->v_ops, vp, uio, cred)
 #define VOP_INACTIVE(vp, td)                           \
-       vop_inactive((vp)->v_ops, vp, td)
+       vop_inactive(*(vp)->v_ops, vp, td)
 #define VOP_RECLAIM(vp, td)                            \
-       vop_reclaim((vp)->v_ops, vp, td)
+       vop_reclaim(*(vp)->v_ops, vp, td)
 #define VOP_LOCK(vp, flags, td)                                \
-       vop_lock((vp)->v_ops, vp, flags, td)
+       vop_lock(*(vp)->v_ops, vp, flags, td)
 #define VOP_UNLOCK(vp, flags, td)                      \
-       vop_unlock((vp)->v_ops, vp, flags, td)
+       vop_unlock(*(vp)->v_ops, vp, flags, td)
 #define VOP_BMAP(vp, bn, vpp, bnp, runp, runb)         \
-       vop_bmap((vp)->v_ops, vp, bn, vpp, bnp, runp, runb)
+       vop_bmap(*(vp)->v_ops, vp, bn, vpp, bnp, runp, runb)
 #define VOP_STRATEGY(vp, bp)                           \
-       vop_strategy((vp)->v_ops, vp, bp)
+       vop_strategy(*(vp)->v_ops, vp, bp)
 #define VOP_PRINT(vp)                                  \
-       vop_print((vp)->v_ops, vp)
+       vop_print(*(vp)->v_ops, vp)
 #define VOP_PATHCONF(vp, name, retval)                 \
-       vop_pathconf((vp)->v_ops, vp, name, retval)
+       vop_pathconf(*(vp)->v_ops, vp, name, retval)
 #define VOP_ADVLOCK(vp, id, op, fl, flags)             \
-       vop_advlock((vp)->v_ops, vp, id, op, fl, flags)
+       vop_advlock(*(vp)->v_ops, vp, id, op, fl, flags)
 #define VOP_BALLOC(vp, offset, size, cred, flags, bpp) \
-       vop_balloc((vp)->v_ops, vp, offset, size, cred, flags, bpp)
+       vop_balloc(*(vp)->v_ops, vp, offset, size, cred, flags, bpp)
 #define VOP_REALLOCBLKS(vp, buflist)                   \
-       vop_reallocblks((vp)->v_ops, vp, buflist)
+       vop_reallocblks(*(vp)->v_ops, vp, buflist)
 #define VOP_GETPAGES(vp, m, count, reqpage, off)       \
-       vop_getpages((vp)->v_ops, vp, m, count, reqpage, off)
+       vop_getpages(*(vp)->v_ops, vp, m, count, reqpage, off)
 #define VOP_PUTPAGES(vp, m, count, sync, rtvals, off)  \
-       vop_putpages((vp)->v_ops, vp, m, count, sync, rtvals, off)
+       vop_putpages(*(vp)->v_ops, vp, m, count, sync, rtvals, off)
 #define VOP_FREEBLKS(vp, addr, length)                 \
-       vop_freeblks((vp)->v_ops, vp, addr, length)
+       vop_freeblks(*(vp)->v_ops, vp, addr, length)
 #define VOP_BWRITE(vp, bp)                             \
-       vop_bwrite((vp)->v_ops, vp, bp)
+       vop_bwrite(*(vp)->v_ops, vp, bp)
 #define VOP_GETACL(vp, type, aclp, cred, td)           \
-       vop_getacl((vp)->v_ops, vp, type, aclp, cred, td)
+       vop_getacl(*(vp)->v_ops, vp, type, aclp, cred, td)
 #define VOP_SETACL(vp, type, aclp, cred, td)           \
-       vop_setacl((vp)->v_ops, vp, type, aclp, cred, td)
+       vop_setacl(*(vp)->v_ops, vp, type, aclp, cred, td)
 #define VOP_ACLCHECK(vp, type, aclp, cred, td)         \
-       vop_aclcheck((vp)->v_ops, vp, type, aclp, cred, td)
+       vop_aclcheck(*(vp)->v_ops, vp, type, aclp, cred, td)
 #define VOP_GETEXTATTR(vp, name, uio, cred, td)                \
-       vop_getextattr((vp)->v_ops, vp, name, uio, cred, td)
+       vop_getextattr(*(vp)->v_ops, vp, name, uio, cred, td)
 #define VOP_SETEXTATTR(vp, name, uio, cred, td)                \
-       vop_setextattr((vp)->v_ops, vp, name, uio, cred, td)
+       vop_setextattr(*(vp)->v_ops, vp, name, uio, cred, td)
 #define VOP_CREATEVOBJECT(vp, td)                      \
-       vop_createvobject((vp)->v_ops, vp, td)
+       vop_createvobject(*(vp)->v_ops, vp, td)
 #define VOP_DESTROYVOBJECT(vp)                         \
-       vop_destroyvobject((vp)->v_ops, vp)
+       vop_destroyvobject(*(vp)->v_ops, vp)
 #define VOP_GETVOBJECT(vp, objpp)                      \
-       vop_getvobject((vp)->v_ops, vp, objpp)
+       vop_getvobject(*(vp)->v_ops, vp, objpp)
 /* no VOP_VFSSET() */
 
 /*
@@ -1117,25 +1114,25 @@ extern struct vnodeop_desc vop_nrename_desc;
  * the VFS's.
  */
 #define VOP_OLD_LOOKUP(dvp, vpp, cnp)                  \
-       vop_lookup((dvp)->v_ops, dvp, vpp, cnp)
+       vop_lookup(*(dvp)->v_ops, dvp, vpp, cnp)
 #define VOP_OLD_CREATE(dvp, vpp, cnp, vap)             \
-       vop_create((dvp)->v_ops, dvp, vpp, cnp, vap)
+       vop_create(*(dvp)->v_ops, dvp, vpp, cnp, vap)
 #define VOP_OLD_MKDIR(dvp, vpp, cnp, vap)              \
-       vop_mkdir((dvp)->v_ops, dvp, vpp, cnp, vap)
+       vop_mkdir(*(dvp)->v_ops, dvp, vpp, cnp, vap)
 #define VOP_OLD_MKNOD(dvp, vpp, cnp, vap)              \
-       vop_mknod((dvp)->v_ops, dvp, vpp, cnp, vap)
+       vop_mknod(*(dvp)->v_ops, dvp, vpp, cnp, vap)
 #define VOP_OLD_LINK(tdvp, vp, cnp)                    \
-       vop_link((tdvp)->v_ops, tdvp, vp, cnp)
+       vop_link(*(tdvp)->v_ops, tdvp, vp, cnp)
 #define VOP_OLD_SYMLINK(dvp, vpp, cnp, vap, target)    \
-       vop_symlink((dvp)->v_ops, dvp, vpp, cnp, vap, target)
+       vop_symlink(*(dvp)->v_ops, dvp, vpp, cnp, vap, target)
 #define VOP_OLD_WHITEOUT(dvp, cnp, flags)              \
-       vop_whiteout((dvp)->v_ops, dvp, cnp, flags)
+       vop_whiteout(*(dvp)->v_ops, dvp, cnp, flags)
 #define VOP_OLD_RENAME(fdvp, fvp, fcnp, tdvp, tvp, tcnp) \
-       vop_rename((fdvp)->v_ops, fdvp, fvp, fcnp, tdvp, tvp, tcnp)
+       vop_rename(*(fdvp)->v_ops, fdvp, fvp, fcnp, tdvp, tvp, tcnp)
 #define VOP_OLD_RMDIR(dvp, vp, cnp)                    \
-       vop_rmdir((dvp)->v_ops, dvp, vp, cnp)
+       vop_rmdir(*(dvp)->v_ops, dvp, vp, cnp)
 #define VOP_OLD_REMOVE(dvp, vp, cnp)                   \
-       vop_remove((dvp)->v_ops, dvp, vp, cnp)
+       vop_remove(*(dvp)->v_ops, dvp, vp, cnp)
 
 /*
  * 'NEW' VOP calls.  These calls use namespaces as an operational basis
@@ -1145,25 +1142,25 @@ extern struct vnodeop_desc vop_nrename_desc;
  * routines.
  */
 #define VOP_NRESOLVE(ncp, cred)                                \
-       vop_nresolve((ncp)->nc_mount->mnt_vn_ops, ncp, cred)
+       vop_nresolve((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred)
 #define VOP_NCREATE(ncp, vpp, cred, vap)               \
-       vop_ncreate((ncp)->nc_mount->mnt_vn_ops, ncp, vpp, cred, vap)
+       vop_ncreate((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap)
 #define VOP_NMKDIR(ncp, vpp, cred, vap)                        \
-       vop_nmkdir((ncp)->nc_mount->mnt_vn_ops, ncp, vpp, cred, vap)
+       vop_nmkdir((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap)
 #define VOP_NMKNOD(ncp, vpp, cred, vap)                        \
-       vop_nmknod((ncp)->nc_mount->mnt_vn_ops, ncp, vpp, cred, vap)
+       vop_nmknod((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap)
 #define VOP_NLINK(ncp, vp, cred)                       \
-       vop_nlink((ncp)->nc_mount->mnt_vn_ops, ncp, vp, cred)
+       vop_nlink((ncp)->nc_mount->mnt_vn_use_ops, ncp, vp, cred)
 #define VOP_NSYMLINK(ncp, vpp, cred, vap, target)      \
-       vop_nsymlink((ncp)->nc_mount->mnt_vn_ops, ncp, vpp, cred, vap, target)
+       vop_nsymlink((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap, target)
 #define VOP_NWHITEOUT(ncp, cred, flags)                        \
-       vop_nwhiteout((ncp)->nc_mount->mnt_vn_ops, ncp, cred, flags)
+       vop_nwhiteout((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred, flags)
 #define VOP_NRENAME(fncp, tncp, cred)                  \
-       vop_nrename((fncp)->nc_mount->mnt_vn_ops, fncp, tncp, cred)
+       vop_nrename((fncp)->nc_mount->mnt_vn_use_ops, fncp, tncp, cred)
 #define VOP_NRMDIR(ncp, cred)                          \
-       vop_nrmdir((ncp)->nc_mount->mnt_vn_ops, ncp, cred)
+       vop_nrmdir((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred)
 #define VOP_NREMOVE(ncp, cred)                         \
-       vop_nremove((ncp)->nc_mount->mnt_vn_ops, ncp, cred)
+       vop_nremove((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred)
 
 #endif
 
index 48a5e64..e2d5fcf 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)vnode.h     8.7 (Berkeley) 2/4/94
  * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/sys/vnode.h,v 1.27 2004/11/18 13:09:53 dillon Exp $
+ * $DragonFly: src/sys/sys/vnode.h,v 1.28 2004/12/17 00:18:09 dillon Exp $
  */
 
 #ifndef _SYS_VNODE_H_
  */
 TAILQ_HEAD(buflists, buf);
 
+/*
+ * Range locks protect offset ranges in files and directories at a high
+ * level, allowing the actual I/O to be broken down into smaller pieces.
+ * Range locks will eventually be integrated into the clustered cache
+ * coherency infrastructure.
+ *
+ * We use a simple data structure for now, but eventually this should 
+ * probably be a btree or red-black tree.
+ */
+struct vrangelock;
+
+TAILQ_HEAD(vrangelock_list, vrangelock);
+
+struct vrangehead {
+       struct vrangelock_list  vh_list;
+};
+
+struct vrangelock {
+       TAILQ_ENTRY(vrangelock) vr_node;
+       int             vr_flags;
+       off_t           vr_offset;
+       off_t           vr_length;
+};
+
+#define RNGL_WAITING   0x0001          /* waiting for lock, else has lock */
+#define RNGL_CHECK     0x0002          /* check for work on unlock */
+#define RNGL_SHARED    0x0004          /* shared lock, else exclusive */
+#define RNGL_ONLIST    0x0008          /* sanity check */
+
+static __inline
+void
+vrange_init(struct vrangelock *vr, int flags, off_t offset, off_t length)
+{
+       vr->vr_flags = flags;
+       vr->vr_offset = offset;
+       vr->vr_length = length;
+}
+
+#ifdef _KERNEL
+
+void   vrange_lock(struct vnode *vp, struct vrangelock *vr);
+void   vrange_unlock(struct vnode *vp, struct vrangelock *vr);
+
+static __inline
+void
+vrange_lock_shared(struct vnode *vp, struct vrangelock *vr, 
+                   off_t offset, off_t length)
+{
+       vrange_init(vr, RNGL_SHARED, offset, length);
+       vrange_lock(vp, vr);
+}
+
+static __inline
+void
+vrange_lock_excl(struct vnode *vp, struct vrangelock *vr,
+                   off_t offset, off_t length)
+{
+       vrange_init(vr, 0, offset, length);
+       vrange_lock(vp, vr);
+}
+
+#endif
 
 /*
- * Reading or writing any of these items requires holding the appropriate lock.
- * v_freelist is locked by the global vnode_free_list token.
- * v_mntvnodes is locked by the global mntvnodes token.
- * v_flag, v_usecount, v_holdcount and v_writecount are
- *    locked by the v_interlock token.
- * v_pollinfo is locked by the lock contained inside it.
+ * The vnode infrastructure is being reorgranized.  Most reference-related
+ * fields are locked by the BGL, and most file I/O related operations and
+ * vnode teardown functions are locked by the vnode lock.
+ *
+ * File read operations require a shared lock, file write operations require
+ * an exclusive lock.  Most directory operations (read or write) currently
+ * require an exclusive lock due to the side effects stored in the directory
+ * inode (which we intend to fix).
+ *
+ * File reads and writes are further protected by a range lock.  The intention
+ * is to be able to break I/O operations down into more easily managed pieces
+ * so vm_page arrays can be passed through rather then UIOs.  This work will
+ * occur in multiple stages.  The range locks will also eventually be used to
+ * deal with clustered cache coherency issues and, more immediately, to
+ * protect operations associated with the kernel-managed journaling module.
  *
  * NOTE: XXX v_opencount currently only used by specfs.  It should be used
  *      universally.  
  *
- * NOTE: The v_vnlock pointer is now an embedded lock structure, v_lock.
- *      v_lock is currently locked exclusively for writes but when a
- *      range lock is added later on it will be locked shared for writes
- *      and a range will be exclusively reserved in the rangelock space.
- *      v_lock is currently locked exclusively for directory modifying
- *      operations but when we start locking namespaces it will no longer
- *      be used for that function, only for the actual I/O on the directory.
+ * NOTE: The vnode operations vector, v_ops, is a double-indirect that
+ *      typically points to &v_mount->mnt_vn_use_ops.  We use a double
+ *      pointer because mnt_vn_use_ops may change dynamically when e.g.
+ *      journaling is turned on or off.
  */
 struct vnode {
        u_long  v_flag;                         /* vnode flags (see below) */
@@ -92,7 +160,7 @@ struct vnode {
        int     v_opencount;                    /* number of explicit opens */
        u_long  v_id;                           /* capability identifier */
        struct  mount *v_mount;                 /* ptr to vfs we are in */
-       struct  vop_ops *v_ops;                 /* mount, vops, other things */
+       struct  vop_ops **v_ops;                /* vnode operations vector */
        TAILQ_ENTRY(vnode) v_freelist;          /* vnode freelist */
        TAILQ_ENTRY(vnode) v_nmntvnodes;        /* vnodes for mount point */
        struct  buflists v_cleanblkhd;          /* clean blocklist head */
@@ -127,6 +195,7 @@ struct vnode {
                short   vpi_revents;            /* what has happened */
        } v_pollinfo;
        struct vmresident *v_resident;          /* optional vmresident */
+       struct vrangehead v_range;              /* range lock */
 #ifdef DEBUG_LOCKS
        const char *filename;                   /* Source file doing locking */
        int line;                               /* Line number doing locking */
@@ -520,8 +589,11 @@ void       cvtnstat (struct stat *sb, struct nstat *nsb);
 struct vnode *allocvnode(int lktimeout, int lkflags);
 struct vnode *allocvnode_placemarker(void);
 void freevnode_placemarker(struct vnode *);
-int    getnewvnode (enum vtagtype tag, struct mount *mp, struct vop_ops *ops,
+int    getnewvnode (enum vtagtype tag, struct mount *mp, 
                    struct vnode **vpp, int timo, int lkflags);
+int    getspecialvnode (enum vtagtype tag, struct mount *mp, 
+                   struct vop_ops **ops, struct vnode **vpp, int timo, 
+                   int lkflags);
 int    lease_check (struct vop_lease_args *ap);
 int    spec_vnoperate (struct vop_generic_args *);
 int    speedup_syncer (void);
@@ -530,7 +602,8 @@ int vcount (struct vnode *vp);
 int    vfinddev (dev_t dev, enum vtype type, struct vnode **vpp);
 void   vfs_add_vnodeops_sysinit (const void *);
 void   vfs_rm_vnodeops_sysinit (const void *);
-void   vfs_add_vnodeops(struct vop_ops **, struct vnodeopv_entry_desc *);
+void   vfs_add_vnodeops(struct mount *, struct vop_ops **,
+                       struct vnodeopv_entry_desc *);
 void   vfs_rm_vnodeops(struct vop_ops **);
 int    vflush (struct mount *mp, int rootrefs, int flags);
 int    vmntvnodescan(struct mount *mp, int flags,
@@ -627,7 +700,6 @@ void        vfs_sync_init(void);
 void   vn_syncer_add_to_worklist(struct vnode *, int);
 void   vnlru_proc_wait(void);
 
-
 extern struct vop_ops *default_vnode_vops;
 extern struct vop_ops *spec_vnode_vops;
 extern struct vop_ops *dead_vnode_vops;
index 8271916..50f8cb8 100644 (file)
@@ -28,7 +28,7 @@
  * 
  *     @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
  * $FreeBSD: src/sys/coda/coda_vnops.c,v 1.22.2.1 2001/06/29 16:26:22 shafeeq Exp $
- * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.23 2004/11/12 00:09:28 dillon Exp $
+ * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.24 2004/12/17 00:18:14 dillon Exp $
  * 
  */
 
@@ -1872,7 +1872,7 @@ make_coda_node(ViceFid *fid, struct mount *vfsp, short type)
        cp = coda_alloc();
        cp->c_fid = *fid;
        
-       err = getnewvnode(VT_CODA, vfsp, vfsp->mnt_vn_ops, &vp, 0, 0);
+       err = getnewvnode(VT_CODA, vfsp, &vp, 0, 0);
        if (err) {                                                
            panic("coda: getnewvnode returned error %d\n", err);   
        }                                                         
index 3dbe583..f837ca6 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)fdesc_vfsops.c      8.4 (Berkeley) 1/21/94
  *
  * $FreeBSD: src/sys/miscfs/fdesc/fdesc_vfsops.c,v 1.22.2.3 2002/08/23 17:42:39 njl Exp $
- * $DragonFly: src/sys/vfs/fdesc/fdesc_vfsops.c,v 1.10 2004/10/12 19:20:53 dillon Exp $
+ * $DragonFly: src/sys/vfs/fdesc/fdesc_vfsops.c,v 1.11 2004/12/17 00:18:18 dillon Exp $
  */
 
 /*
@@ -88,7 +88,7 @@ fdesc_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
        if (mp->mnt_flag & MNT_UPDATE)
                return (EOPNOTSUPP);
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, fdesc_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, fdesc_vnodeop_entries);
 
        error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, td);
        if (error)
index ce76d10..401eb76 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)fdesc_vnops.c       8.9 (Berkeley) 1/21/94
  *
  * $FreeBSD: src/sys/miscfs/fdesc/fdesc_vnops.c,v 1.47.2.1 2001/10/22 22:49:26 chris Exp $
- * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.15 2004/10/12 19:20:53 dillon Exp $
+ * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.16 2004/12/17 00:18:18 dillon Exp $
  */
 
 /*
@@ -130,7 +130,7 @@ loop:
         */
        MALLOC(fd, struct fdescnode *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
 
-       error = getnewvnode(VT_FDESC, mp, mp->mnt_vn_ops, vpp, 0, 0);
+       error = getnewvnode(VT_FDESC, mp, vpp, 0, 0);
        if (error) {
                FREE(fd, M_TEMP);
                goto out;
index e54f392..cdfc226 100644 (file)
@@ -38,7 +38,7 @@
  *
  *     @(#)ffs_vfsops.c        8.8 (Berkeley) 4/18/94
  *     $FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $
- *     $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.22 2004/11/12 00:09:30 dillon Exp $
+ *     $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.23 2004/12/17 00:18:20 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -752,9 +752,9 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td)
                ump->um_quotas[i] = NULLVP; 
        dev->si_mountpoint = mp;
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, ext2_vnodeop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_spec_ops, ext2_specop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_fifo_ops, ext2_fifoop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, ext2_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_spec_ops, ext2_specop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_fifo_ops, ext2_fifoop_entries);
 
        if (ronly == 0) 
                ext2_sbupdate(ump, MNT_WAIT);
@@ -1037,7 +1037,7 @@ restart:
        MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
 
        /* Allocate a new vnode/inode. */
-       if ((error = getnewvnode(VT_UFS, mp, mp->mnt_vn_ops, &vp, 0, 0)) != 0) {
+       if ((error = getnewvnode(VT_UFS, mp, &vp, 0, 0)) != 0) {
                if (ext2fs_inode_hash_lock < 0)
                        wakeup(&ext2fs_inode_hash_lock);
                ext2fs_inode_hash_lock = 0;
index 4ada31e..680b59d 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/hpfs/hpfs_vfsops.c,v 1.3.2.2 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.23 2004/11/12 00:09:33 dillon Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.24 2004/12/17 00:18:22 dillon Exp $
  */
 
 
@@ -393,7 +393,7 @@ hpfs_mountfs(struct vnode *devvp, struct mount *mp, struct hpfs_args *argsp,
                hpfs_bmdeinit(hpmp);
                goto failed;
        }
-       vfs_add_vnodeops(&mp->mnt_vn_ops, hpfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, hpfs_vnodeop_entries);
 
        error = hpfs_root(mp, &vp);
        if (error) {
@@ -612,8 +612,7 @@ hpfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
        MALLOC(hp, struct hpfsnode *, sizeof(struct hpfsnode), 
                M_HPFSNO, M_WAITOK);
 
-       error = getnewvnode(VT_HPFS, hpmp->hpm_mp, hpmp->hpm_mp->mnt_vn_ops,
-                           &vp, VLKTIMEOUT, 0);
+       error = getnewvnode(VT_HPFS, hpmp->hpm_mp, &vp, VLKTIMEOUT, 0);
        if (error) {
                printf("hpfs_vget: can't get new vnode\n");
                FREE(hp, M_HPFSNO);
index df729e3..61e19d0 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)cd9660_vfsops.c     8.18 (Berkeley) 5/22/95
  * $FreeBSD: src/sys/isofs/cd9660/cd9660_vfsops.c,v 1.74.2.7 2002/04/08 09:39:29 bde Exp $
- * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.23 2004/11/12 00:09:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.24 2004/12/17 00:18:23 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -513,9 +513,9 @@ iso_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td,
                supbp = NULL;
        }
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, cd9660_vnodeop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_spec_ops, cd9660_specop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_fifo_ops, cd9660_fifoop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, cd9660_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_spec_ops, cd9660_specop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_fifo_ops, cd9660_fifoop_entries);
 
        return 0;
 out:
@@ -713,7 +713,7 @@ again:
                return (0);
 
        /* Allocate a new vnode/iso_node. */
-       error = getnewvnode(VT_ISOFS, mp, mp->mnt_vn_ops, &vp, 0, 0);
+       error = getnewvnode(VT_ISOFS, mp, &vp, 0, 0);
        if (error) {
                *vpp = NULLVP;
                return (error);
@@ -848,11 +848,11 @@ again:
         */
        switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) {
        case VFIFO:
-               vp->v_ops = mp->mnt_vn_fifo_ops;
+               vp->v_ops = &mp->mnt_vn_fifo_ops;
                break;
        case VCHR:
        case VBLK:
-               vp->v_ops = mp->mnt_vn_spec_ops;
+               vp->v_ops = &mp->mnt_vn_spec_ops;
                addaliasu(vp, ip->inode.iso_rdev);
                break;
        default:
index 5be58ca..4c2d6c1 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)mfs_vfsops.c        8.11 (Berkeley) 6/19/95
  * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $
- * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.19 2004/10/12 19:20:59 dillon Exp $
+ * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.20 2004/12/17 00:18:25 dillon Exp $
  */
 
 
@@ -288,7 +288,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
         */
        MALLOC(mfsp, struct mfsnode *, sizeof *mfsp, M_MFSNODE, M_WAITOK);
 
-       err = getnewvnode(VT_MFS, NULL, mfs_vnode_vops, &devvp, 0, 0);
+       err = getspecialvnode(VT_MFS, NULL, &mfs_vnode_vops, &devvp, 0, 0);
        if (err) {
                FREE(mfsp, M_MFSNODE);
                goto error_1;
index 7253fe0..fdf8d74 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/msdosfs/msdosfs_denode.c,v 1.47.2.3 2002/08/22 16:20:15 trhodes Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_denode.c,v 1.18 2004/10/27 08:57:48 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_denode.c,v 1.19 2004/12/17 00:18:26 dillon Exp $ */
 /*     $NetBSD: msdosfs_denode.c,v 1.28 1998/02/10 14:10:00 mrg Exp $  */
 
 /*-
@@ -293,8 +293,7 @@ again:
         */
 
        /* getnewvnode() does a vref() on the vnode */
-       error = getnewvnode(VT_MSDOSFS, mntp, mntp->mnt_vn_ops, &nvp,
-                           VLKTIMEOUT, 0);
+       error = getnewvnode(VT_MSDOSFS, mntp, &nvp, VLKTIMEOUT, 0);
        if (error) {
                *depp = NULL;
                FREE(ldep, M_MSDOSFSNODE);
index eaab265..2f92223 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/msdosfs/Attic/msdosfs_vfsops.c,v 1.60.2.8 2004/03/02 09:43:04 tjr Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.21 2004/11/12 00:09:36 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.22 2004/12/17 00:18:26 dillon Exp $ */
 /*     $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $   */
 
 /*-
@@ -731,7 +731,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp, struct thread *td,
        mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
        mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
        mp->mnt_flag |= MNT_LOCAL;
-       vfs_add_vnodeops(&mp->mnt_vn_ops, msdosfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, msdosfs_vnodeop_entries);
        dev->si_mountpoint = mp;
 
        return 0;
index 59e0236..8e5d272 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_node.c  8.6 (Berkeley) 5/22/95
  * $FreeBSD: src/sys/nfs/nfs_node.c,v 1.36.2.3 2002/01/05 22:25:04 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_node.c,v 1.17 2004/10/12 19:21:01 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_node.c,v 1.18 2004/12/17 00:18:28 dillon Exp $
  */
 
 
@@ -150,8 +150,7 @@ loop:
         */
        np = zalloc(nfsnode_zone);
                
-       error = getnewvnode(VT_NFS, mntp, mntp->mnt_vn_ops, &nvp,
-                               0, LK_NOPAUSE);
+       error = getnewvnode(VT_NFS, mntp, &nvp, 0, LK_NOPAUSE);
        if (error) {
                if (nfs_node_hash_lock < 0)
                        wakeup(&nfs_node_hash_lock);
index c1caa7e..582f44c 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_subs.c  8.8 (Berkeley) 5/22/95
  * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.23 2004/11/12 00:09:37 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.24 2004/12/17 00:18:28 dillon Exp $
  */
 
 /*
@@ -1241,12 +1241,12 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        if (vp->v_type != vtyp) {
                vp->v_type = vtyp;
                if (vp->v_type == VFIFO) {
-                       vp->v_ops = vp->v_mount->mnt_vn_fifo_ops;
+                       vp->v_ops = &vp->v_mount->mnt_vn_fifo_ops;
                } else if (vp->v_type == VCHR || vp->v_type == VBLK) {
-                       vp->v_ops = vp->v_mount->mnt_vn_spec_ops;
+                       vp->v_ops = &vp->v_mount->mnt_vn_spec_ops;
                        addaliasu(vp, rdev);
                } else {
-                       vp->v_ops = vp->v_mount->mnt_vn_ops;
+                       vp->v_ops = &vp->v_mount->mnt_vn_use_ops;
                }
                np->n_mtime = mtime.tv_sec;
        }
index fa12983..611eedf 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vfsops.c        8.12 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/nfs/nfs_vfsops.c,v 1.91.2.7 2003/01/27 20:04:08 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.22 2004/10/12 19:21:01 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.23 2004/12/17 00:18:28 dillon Exp $
  */
 
 #include "opt_bootp.h"
@@ -957,9 +957,9 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
        /*
         * Install vop_ops for our vnops
         */
-       vfs_add_vnodeops(&mp->mnt_vn_ops, nfsv2_vnodeop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_spec_ops, nfsv2_specop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_fifo_ops, nfsv2_fifoop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, nfsv2_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_spec_ops, nfsv2_specop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_fifo_ops, nfsv2_fifoop_entries);
 
        /*
         * A reference count is needed on the nfsnode representing the
index d2535e6..b2f51fc 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ntfs/ntfs_vfsops.c,v 1.20.2.5 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.24 2004/11/12 00:09:38 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.25 2004/12/17 00:18:29 dillon Exp $
  */
 
 
@@ -512,7 +512,7 @@ ntfs_mountfs(struct vnode *devvp, struct mount *mp, struct ntfs_args *argsp,
                (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"",
                ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode));
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, ntfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, ntfs_vnodeop_entries);
 
        /*
         * We read in some system nodes to do not allow 
@@ -921,9 +921,7 @@ ntfs_vgetex(struct mount *mp, ino_t ino, u_int32_t attrtype, char *attrname,
                return (0);
        }
 
-       error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, 
-                           ntmp->ntm_mountp->mnt_vn_ops, &vp,
-                           VLKTIMEOUT, 0);
+       error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, &vp, VLKTIMEOUT, 0);
        if(error) {
                ntfs_frele(fp);
                ntfs_ntput(ip);
index 3f119c1..0e99481 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)null_subr.c 8.7 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/miscfs/nullfs/null_subr.c,v 1.21.2.4 2001/06/26 04:20:09 bp Exp $
- * $DragonFly: src/sys/vfs/nullfs/Attic/null_subr.c,v 1.16 2004/10/12 19:21:04 dillon Exp $
+ * $DragonFly: src/sys/vfs/nullfs/Attic/null_subr.c,v 1.17 2004/12/17 00:18:30 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -231,7 +231,7 @@ retry:
        MALLOC(np, struct null_node *, sizeof(struct null_node),
               M_NULLFSNODE, M_WAITOK);
 
-       error = getnewvnode(VT_NULL, mp, mp->mnt_vn_ops, vpp, 0, LK_CANRECURSE);
+       error = getnewvnode(VT_NULL, mp, vpp, 0, LK_CANRECURSE);
        if (error) {
                FREE(np, M_NULLFSNODE);
                return (error);
index 0418522..91e2655 100644 (file)
@@ -37,7 +37,7 @@
  *
  * @(#)lofs_vfsops.c   1.2 (Berkeley) 6/18/92
  * $FreeBSD: src/sys/miscfs/nullfs/null_vfsops.c,v 1.35.2.3 2001/07/26 20:37:11 iedowse Exp $
- * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.14 2004/11/12 00:09:40 dillon Exp $
+ * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.15 2004/12/17 00:18:30 dillon Exp $
  */
 
 /*
@@ -158,7 +158,7 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
         */
        xmp->nullm_vfs = lowerrootvp->v_mount;
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, null_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, null_vnodeop_entries);
 
        /*
         * Save reference.  Each mount also holds
index d53b9f5..f15b39a 100644 (file)
@@ -38,7 +38,7 @@
  * Ancestors:
  *     @(#)lofs_vnops.c        1.2 (Berkeley) 6/18/92
  * $FreeBSD: src/sys/miscfs/nullfs/null_vnops.c,v 1.38.2.6 2002/07/31 00:32:28 semenu Exp $
- * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.20 2004/11/12 00:09:40 dillon Exp $
+ * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.21 2004/12/17 00:18:30 dillon Exp $
  *     ...and...
  *     @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
  *
@@ -301,7 +301,7 @@ null_bypass(struct vop_generic_args *ap)
         * lower vp's vop_ops structure.
         */
        if (vps_p[0] && *vps_p[0]) {
-               ap->a_ops = (*(vps_p[0]))->v_ops;
+               ap->a_ops = *(*(vps_p[0]))->v_ops;
                error = vop_vnoperate_ap(ap);
        } else {
                printf("null_bypass: no map for %s\n", descp->vdesc_name);
index b220db8..7d1c73f 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_node.c,v 1.3.2.8 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_node.c,v 1.16 2004/10/12 19:21:05 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_node.c,v 1.17 2004/12/17 00:18:32 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -166,7 +166,7 @@ rescan:
         * elsewhere if MALLOC should block.
         */
        MALLOC(np, struct nwnode *, sizeof *np, M_NWNODE, M_WAITOK | M_ZERO);
-       error = getnewvnode(VT_NWFS, mp, mp->mnt_vn_ops, &vp, 0, 0);
+       error = getnewvnode(VT_NWFS, mp, &vp, 0, 0);
        if (error) {
                *vpp = NULL;
                FREE(np, M_NWNODE);
index a66ad81..af10a0b 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_vfsops.c,v 1.6.2.6 2001/10/25 19:18:54 dillon Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_vfsops.c,v 1.13 2004/10/12 19:21:05 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_vfsops.c,v 1.14 2004/12/17 00:18:32 dillon Exp $
  */
 #include "opt_ncp.h"
 #ifndef NCP
@@ -219,7 +219,7 @@ nwfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
        /* protect against invalid mount points */
        nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0';
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, nwfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, nwfs_vnodeop_entries);
 
        vfs_getnewfsid(mp);
        error = nwfs_root(mp, &vp);
index 18b3155..d6313e9 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)portal_vfsops.c     8.11 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/miscfs/portal/portal_vfsops.c,v 1.26.2.2 2001/07/26 20:37:16 iedowse Exp $
- * $DragonFly: src/sys/vfs/portal/portal_vfsops.c,v 1.13 2004/10/12 19:21:06 dillon Exp $
+ * $DragonFly: src/sys/vfs/portal/portal_vfsops.c,v 1.14 2004/12/17 00:18:33 dillon Exp $
  */
 
 /*
@@ -112,9 +112,9 @@ portal_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
                M_PORTALFSMNT, M_WAITOK);       /* XXX */
 
         
-       vfs_add_vnodeops(&mp->mnt_vn_ops, portal_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, portal_vnodeop_entries);
 
-       error = getnewvnode(VT_PORTAL, mp, mp->mnt_vn_ops, &rvp, 0, 0);
+       error = getnewvnode(VT_PORTAL, mp, &rvp, 0, 0);
        if (error) {
                FREE(fmp, M_PORTALFSMNT);
                FREE(pn, M_TEMP);
index b04345a..db88c11 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)portal_vnops.c      8.14 (Berkeley) 5/21/95
  *
  * $FreeBSD: src/sys/miscfs/portal/portal_vnops.c,v 1.38 1999/12/21 06:29:00 chris Exp $
- * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.17 2004/10/12 19:21:06 dillon Exp $
+ * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.18 2004/12/17 00:18:33 dillon Exp $
  */
 
 /*
@@ -135,8 +135,7 @@ portal_lookup(struct vop_lookup_args *ap)
        MALLOC(pt, struct portalnode *, sizeof(struct portalnode),
                M_TEMP, M_WAITOK);
 
-       error = getnewvnode(VT_PORTAL, dvp->v_mount, dvp->v_mount->mnt_vn_ops,
-                           &fvp, 0, 0);
+       error = getnewvnode(VT_PORTAL, dvp->v_mount, &fvp, 0, 0);
        if (error) {
                FREE(pt, M_TEMP);
                goto bad;
index 6ccdf2f..ac5b0e1 100644 (file)
@@ -37,7 +37,7 @@
  *     @(#)procfs_subr.c       8.6 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/miscfs/procfs/procfs_subr.c,v 1.26.2.3 2002/02/18 21:28:04 des Exp $
- * $DragonFly: src/sys/vfs/procfs/procfs_subr.c,v 1.11 2004/10/12 19:21:07 dillon Exp $
+ * $DragonFly: src/sys/vfs/procfs/procfs_subr.c,v 1.12 2004/12/17 00:18:34 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -141,7 +141,7 @@ loop:
         */
        MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
 
-       error = getnewvnode(VT_PROCFS, mp, mp->mnt_vn_ops, vpp, 0, 0);
+       error = getnewvnode(VT_PROCFS, mp, vpp, 0, 0);
        if (error) {
                free(pfs, M_TEMP);
                goto out;
index a56b596..2f6fefd 100644 (file)
@@ -37,7 +37,7 @@
  *     @(#)procfs_vfsops.c     8.7 (Berkeley) 5/10/95
  *
  * $FreeBSD: src/sys/miscfs/procfs/procfs_vfsops.c,v 1.32.2.1 2001/10/15 20:42:01 des Exp $
- * $DragonFly: src/sys/vfs/procfs/procfs_vfsops.c,v 1.9 2004/09/30 19:00:19 dillon Exp $
+ * $DragonFly: src/sys/vfs/procfs/procfs_vfsops.c,v 1.10 2004/12/17 00:18:34 dillon Exp $
  */
 
 /*
@@ -92,7 +92,7 @@ procfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
        bcopy("procfs", mp->mnt_stat.f_mntfromname, size);
        bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
        procfs_statfs(mp, &mp->mnt_stat, td);
-       vfs_add_vnodeops(&mp->mnt_vn_ops, procfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, procfs_vnodeop_entries);
 
        return (0);
 }
index 7f48652..a383f09 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_node.c,v 1.2.2.3 2003/01/17 08:20:26 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_node.c,v 1.15 2004/10/12 19:21:08 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_node.c,v 1.16 2004/12/17 00:18:35 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -229,8 +229,7 @@ loop:
                return ENOENT;
 
        MALLOC(np, struct smbnode *, sizeof *np, M_SMBNODE, M_WAITOK);
-       error = getnewvnode(VT_SMBFS, mp, mp->mnt_vn_ops, &vp,
-                           VLKTIMEOUT, LK_CANRECURSE);
+       error = getnewvnode(VT_SMBFS, mp, &vp, VLKTIMEOUT, LK_CANRECURSE);
        if (error) {
                FREE(np, M_SMBNODE);
                return error;
index d24a86c..3293116 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_vfsops.c,v 1.2.2.5 2003/01/17 08:20:26 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_vfsops.c,v 1.15 2004/10/12 19:21:08 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_vfsops.c,v 1.16 2004/12/17 00:18:35 dillon Exp $
  */
 #include "opt_netsmb.h"
 #ifndef NETSMB
@@ -222,7 +222,7 @@ smbfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
        smp->sm_args.mount_point[sizeof(smp->sm_args.mount_point) - 1] = '\0';
        vfs_getnewfsid(mp);
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, smbfs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, smbfs_vnodeop_entries);
 
        error = smbfs_root(mp, &vp);
        if (error)
index 3ba8222..18f5b5f 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.16 2003/11/05 06:56:08 scottl Exp $
- * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.10 2004/11/12 00:09:51 dillon Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.11 2004/12/17 00:18:36 dillon Exp $
  */
 
 /* udf_vfsops.c */
@@ -370,7 +370,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td)
                goto bail;
        } 
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, udf_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, udf_vnodeop_entries);
 
        /*
         * Find the file entry for the root directory.
index 198e234..f754c5c 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.33 2003/12/07 05:04:49 scottl Exp $
- * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.10 2004/11/12 00:09:51 dillon Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.11 2004/12/17 00:18:36 dillon Exp $
  */
 
 /* udf_vnops.c */
@@ -175,7 +175,7 @@ udf_allocv(struct mount *mp, struct vnode **vpp)
        int error;
        struct vnode *vp;
 
-       error = getnewvnode(VT_UDF, mp, mp->mnt_vn_ops, &vp, 0, 0);
+       error = getnewvnode(VT_UDF, mp, &vp, 0, 0);
        if (error) {
                printf("udf_allocv: failed to allocate new vnode\n");
                return(error);
index 48d6888..0146b0f 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ffs_vfsops.c        8.31 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $
- * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.28 2004/11/12 00:09:52 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.29 2004/12/17 00:18:44 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -789,9 +789,9 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td,
                fs->fs_clean = 0;
                (void) ffs_sbupdate(ump, MNT_WAIT);
        }
-       vfs_add_vnodeops(&mp->mnt_vn_ops, ffs_vnodeop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_spec_ops, ffs_specop_entries);
-       vfs_add_vnodeops(&mp->mnt_vn_fifo_ops, ffs_fifoop_entries); 
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, ffs_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_spec_ops, ffs_specop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_fifo_ops, ffs_fifoop_entries); 
 
        return (0);
 out:
@@ -1110,8 +1110,7 @@ restart:
            ump->um_malloctype, M_WAITOK);
 
        /* Allocate a new vnode/inode. */
-       error = getnewvnode(VT_UFS, mp, mp->mnt_vn_ops, &vp,
-                           VLKTIMEOUT, LK_CANRECURSE);
+       error = getnewvnode(VT_UFS, mp, &vp, VLKTIMEOUT, LK_CANRECURSE);
        if (error) {
                *vpp = NULL;
                free(ip, ump->um_malloctype);
index 59c9097..7d98efe 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.24 2004/11/12 00:09:52 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.25 2004/12/17 00:18:44 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -2014,11 +2014,11 @@ ufs_vinit(struct mount *mntp, struct vnode **vpp)
        switch(vp->v_type = IFTOVT(ip->i_mode)) {
        case VCHR:
        case VBLK:
-               vp->v_ops = mntp->mnt_vn_spec_ops;
+               vp->v_ops = &mntp->mnt_vn_spec_ops;
                addaliasu(vp, ip->i_rdev);
                break;
        case VFIFO:
-               vp->v_ops = mntp->mnt_vn_fifo_ops;
+               vp->v_ops = &mntp->mnt_vn_fifo_ops;
                break;
        default:
                break;
index 16abc5f..7f4a142 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)umap_subr.c 8.9 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/miscfs/umapfs/umap_subr.c,v 1.19 1999/09/04 11:51:41 bde Exp $
- * $DragonFly: src/sys/vfs/umapfs/Attic/umap_subr.c,v 1.12 2004/10/12 19:21:13 dillon Exp $
+ * $DragonFly: src/sys/vfs/umapfs/Attic/umap_subr.c,v 1.13 2004/12/17 00:18:46 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -201,7 +201,7 @@ umap_node_alloc(struct mount *mp, struct vnode *lowervp, struct vnode **vpp)
        MALLOC(xp, struct umap_node *, sizeof(struct umap_node),
            M_TEMP, M_WAITOK);
 
-       error = getnewvnode(VT_UMAP, mp, mp->mnt_vn_ops, vpp, 0, 0);
+       error = getnewvnode(VT_UMAP, mp, vpp, 0, 0);
        if (error) {
                FREE(xp, M_TEMP);
                return (error);
index febce56..db83c0e 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)umap_vfsops.c       8.8 (Berkeley) 5/14/95
  *
  * $FreeBSD: src/sys/miscfs/umapfs/umap_vfsops.c,v 1.31.2.2 2001/09/11 09:49:53 kris Exp $
- * $DragonFly: src/sys/vfs/umapfs/Attic/umap_vfsops.c,v 1.14 2004/11/12 00:09:53 dillon Exp $
+ * $DragonFly: src/sys/vfs/umapfs/Attic/umap_vfsops.c,v 1.15 2004/12/17 00:18:46 dillon Exp $
  */
 
 /*
@@ -197,7 +197,7 @@ umapfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
                    amp->info_gmapdata[i][1]);
 #endif
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, umap_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, umap_vnodeop_entries);
 
        /*
         * Save reference.  Each mount also holds
index f3c210e..5a0c9a5 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)umap_vnops.c        8.6 (Berkeley) 5/22/95
  * $FreeBSD: src/sys/miscfs/umapfs/umap_vnops.c,v 1.30 1999/08/30 07:08:04 bde Exp $
- * $DragonFly: src/sys/vfs/umapfs/Attic/umap_vnops.c,v 1.12 2004/10/12 19:21:13 dillon Exp $
+ * $DragonFly: src/sys/vfs/umapfs/Attic/umap_vnops.c,v 1.13 2004/12/17 00:18:46 dillon Exp $
  */
 
 /*
@@ -199,7 +199,7 @@ umap_bypass(struct vop_generic_args *ap)
         * Call the operation on the lower layer with the modified argument
         * structure.  We have to adjust a_fm to point at the lower layer.
         */
-       ap->a_ops = (*(vps_p[0]))->v_ops;
+       ap->a_ops = *(*(vps_p[0]))->v_ops;
        error = vop_vnoperate_ap(ap);
 
        /*
index bc2f412..4d9fc32 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     @(#)union_subr.c        8.20 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/miscfs/union/union_subr.c,v 1.43.2.2 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/union/union_subr.c,v 1.17 2004/11/12 00:09:55 dillon Exp $
+ * $DragonFly: src/sys/vfs/union/union_subr.c,v 1.18 2004/12/17 00:18:47 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -528,7 +528,7 @@ loop:
         * Create new node rather then replace old node
         */
 
-       error = getnewvnode(VT_UNION, mp, mp->mnt_vn_ops, vpp, 0, 0);
+       error = getnewvnode(VT_UNION, mp, vpp, 0, 0);
        if (error) {
                /*
                 * If an error occurs clear out vnodes.
index b1b3f50..83ec453 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     @(#)union_vfsops.c      8.20 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/miscfs/union/union_vfsops.c,v 1.39.2.2 2001/10/25 19:18:53 dillon Exp $
- * $DragonFly: src/sys/vfs/union/union_vfsops.c,v 1.17 2004/11/12 00:09:55 dillon Exp $
+ * $DragonFly: src/sys/vfs/union/union_vfsops.c,v 1.18 2004/12/17 00:18:47 dillon Exp $
  */
 
 /*
@@ -272,7 +272,7 @@ union_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
        (void) copyinstr(args.target, cp, len - 1, &size);
        bzero(cp + size, len - size);
 
-       vfs_add_vnodeops(&mp->mnt_vn_ops, union_vnodeop_entries);
+       vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, union_vnodeop_entries);
 
        (void)union_statfs(mp, &mp->mnt_stat, td);
 
index efddc3b..88fcb21 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     @(#)union_vnops.c       8.32 (Berkeley) 6/23/95
  * $FreeBSD: src/sys/miscfs/union/union_vnops.c,v 1.72 1999/12/15 23:02:14 eivind Exp $
- * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.17 2004/11/12 00:09:55 dillon Exp $
+ * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.18 2004/12/17 00:18:47 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -791,7 +791,7 @@ union_close(struct vop_close_args *ap)
                --un->un_openl;
                vp = un->un_lowervp;
        }
-       ap->a_head.a_ops = vp->v_ops;
+       ap->a_head.a_ops = *vp->v_ops;
        ap->a_vp = vp;
        return(vop_close_ap(ap));
 }
@@ -831,7 +831,7 @@ union_access(struct vop_access_args *ap)
        }
 
        if ((vp = union_lock_upper(un, td)) != NULLVP) {
-               ap->a_head.a_ops = vp->v_ops;
+               ap->a_head.a_ops = *vp->v_ops;
                ap->a_vp = vp;
                error = vop_access_ap(ap);
                union_unlock_upper(vp, td);
@@ -840,7 +840,7 @@ union_access(struct vop_access_args *ap)
 
        if ((vp = un->un_lowervp) != NULLVP) {
                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
-               ap->a_head.a_ops = vp->v_ops;
+               ap->a_head.a_ops = *vp->v_ops;
                ap->a_vp = vp;
 
                /*
@@ -1116,7 +1116,7 @@ union_lease(struct vop_lease_args *ap)
 {
        struct vnode *ovp = OTHERVP(ap->a_vp);
 
-       ap->a_head.a_ops = ovp->v_ops;
+       ap->a_head.a_ops = *ovp->v_ops;
        ap->a_vp = ovp;
        return (vop_lease_ap(ap));
 }
@@ -1130,7 +1130,7 @@ union_ioctl(struct vop_ioctl_args *ap)
 {
        struct vnode *ovp = OTHERVP(ap->a_vp);
 
-       ap->a_head.a_ops = ovp->v_ops;
+       ap->a_head.a_ops = *ovp->v_ops;
        ap->a_vp = ovp;
        return(vop_ioctl_ap(ap));
 }
@@ -1144,7 +1144,7 @@ union_poll(struct vop_poll_args *ap)
 {
        struct vnode *ovp = OTHERVP(ap->a_vp);
 
-       ap->a_head.a_ops = ovp->v_ops;
+       ap->a_head.a_ops = *ovp->v_ops;
        ap->a_vp = ovp;
        return(vop_poll_ap(ap));
 }
@@ -1183,7 +1183,7 @@ union_mmap(struct vop_mmap_args *ap)
 {
        struct vnode *ovp = OTHERVP(ap->a_vp);
 
-       ap->a_head.a_ops = ovp->v_ops;
+       ap->a_head.a_ops = *ovp->v_ops;
        ap->a_vp = ovp;
        return (vop_mmap_ap(ap));
 }
@@ -1593,7 +1593,7 @@ union_readdir(struct vop_readdir_args *ap)
        int error = 0;
 
        if ((uvp = union_lock_upper(un, td)) != NULLVP) {
-               ap->a_head.a_ops = uvp->v_ops;
+               ap->a_head.a_ops = *uvp->v_ops;
                ap->a_vp = uvp;
                error = vop_readdir_ap(ap);
                union_unlock_upper(uvp, td);
@@ -1616,7 +1616,7 @@ union_readlink(struct vop_readlink_args *ap)
        vp = union_lock_other(un, td);
        KASSERT(vp != NULL, ("union_readlink: backing vnode missing!"));
 
-       ap->a_head.a_ops = vp->v_ops;
+       ap->a_head.a_ops = *vp->v_ops;
        ap->a_vp = vp;
        error = vop_readlink_ap(ap);
        union_unlock_other(vp, td);
@@ -1808,7 +1808,7 @@ union_pathconf(struct vop_pathconf_args *ap)
        vp = union_lock_other(un, td);
        KASSERT(vp != NULL, ("union_pathconf: backing vnode missing!"));
 
-       ap->a_head.a_ops = vp->v_ops;
+       ap->a_head.a_ops = *vp->v_ops;
        ap->a_vp = vp;
        error = vop_pathconf_ap(ap);
        union_unlock_other(vp, td);
@@ -1825,7 +1825,7 @@ union_advlock(struct vop_advlock_args *ap)
 {
        struct vnode *ovp = OTHERVP(ap->a_vp);
 
-       ap->a_head.a_ops = ovp->v_ops;
+       ap->a_head.a_ops = *ovp->v_ops;
        ap->a_vp = ovp;
        return (vop_advlock_ap(ap));
 }
index 3ed92a6..9def79f 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)vm_swap.c   8.5 (Berkeley) 2/17/94
  * $FreeBSD: src/sys/vm/vm_swap.c,v 1.96.2.2 2001/10/14 18:46:47 iedowse Exp $
- * $DragonFly: src/sys/vm/vm_swap.c,v 1.16 2004/11/12 00:09:56 dillon Exp $
+ * $DragonFly: src/sys/vm/vm_swap.c,v 1.17 2004/12/17 00:18:49 dillon Exp $
  */
 
 #include "opt_swap.h"
@@ -249,7 +249,7 @@ swaponvp(struct thread *td, struct vnode *vp, u_long nblks)
        cred = td->td_proc->p_ucred;
 
        if (!swapdev_vp) {
-               error = getnewvnode(VT_NON, NULL, swapdev_vnode_vops,
+               error = getspecialvnode(VT_NON, NULL, &swapdev_vnode_vops,
                                    &swapdev_vp, 0, 0);
                if (error)
                        panic("Cannot get vnode for swapdev");