VFS messaging/interfacing work stage 7/99. BEGIN DESTABILIZATION!
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 30 Sep 2004 19:00:29 +0000 (19:00 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 30 Sep 2004 19:00:29 +0000 (19:00 +0000)
Implement the infrastructure required to allow us to begin switching to the
new nlookup() VFS API.

filedesc->fd_ncdir, fd_nrdir, fd_njdir

    File descriptors (associated with processes) now record the
    namecache pointer related to the current directory, root directory,
    and jail directory, in addition to the vnode pointers.  These
    pointers are used as the basis for the new path lookup code
    (nlookup() and friends).

file->f_ncp

    File pointers may now have a referenced+unlocked namecache
    pointer associated with them.  All fp's representing directories
    have this attached.  This allows fchdir() to properly record
    the ncp in fdp->fd_ncdir and friends.

mount->mnt_ncp

    The namecache topology for crossing a mount point works as
    follows: when looking up a path element which is a mount point,
    cache_nlookup() will locate the ncp for the vnode-under the
    mount point.  mount->mnt_ncp represents the root of the mount,
    that is the vnode-over.  nlookup() detects the mount point and
    accesses mount->mnt_ncp to skip past the vnode-under.  When going
    backwards (..), nlookup() detects the case and skips backwards.

    The ncp linkages are: ncp->ncp->ncp[vnode_under]->ncp[vnode_over].
    That is, when going forwards or backwards nlookup must explicitly
    skip over the double-ncp when crossing a mount point.  This allows
    us to keep the namecache topology intact across mount points.

NEW CACHE level API functions:

cache_get() Reference and lock a namecache entry
cache_put() Dereference and unlock a namecache entry
cache_lock() lock an already-referenced namecache entry
cache_unlock() unlock a lockednamecache entry

    NOTE: namecache locks are exclusive and recursive.  These are
    the 'namespace' locks that we will be using to guarentee namespace
    operations such as in a CREATE, RENAME, or REMOVE.

vfs_cache_setroot()  Set the new system-wide root directory
cache_allocroot()    System bootstrap helper function to allocate
      the root namecache node.

cache_resolve() Resolve a NCF_UNRESOLVED namecache node.  The
namecache node should be locked on call.

cache_setvp() (resolver) associate a VP or create a negative
cache entry representation for a namecache
pointer and clear NCF_UNRESOLVED.  The
namecache node should be locked on call.

cache_setunresolved() Revert a resolved namecache entry back to an
unresolved state, disassociating any vnode
but leaving the topology intact.  The
namecache node should be locked on call.

cache_vget() Obtain the locked+refd vnode related to
a namecache entry, resolving the entry if
necessary.  Return ENOENT if the entry
represents a negative cache hit.

cache_vref() Obtained a refd (not locked) vnode related to
a namecache entry, as above.

cache_nlookup() The new namecache lookup routine.  This routine
does a lookup and allocates a new namecache
node (into an unresolved state) if necessary.
Returns a namecache record whether or not
the item can be found and whether or not it
represents a positive or negative hit.

cache_lookup() OLD API CODE DEPRECATED, but must be maintained
until everything has been converted over.
cache_enter() OLD API CODE DEPRECATED, but must be maintained
until everything has been converted over.

NEW default VOPs

vop_noresolve() Implements a namecache resolver for VFSs
which are still using the old VOP_LOOKUP/
VOP_CACHEDLOOKUP API (which is all of them
still).

VOP_LOOKUP OLD API CODE DEPRECATED, but must be maintained
until everything has been converted over.
VOP_CACHEDLOOKUP OLD API CODE DEPRECATED, but must be maintained
until everything has been converted over.

NEW PATHNAME LOOKUP CODE

nlookup_init() Similar to NDINIT, initialize a nlookupdata
structure for nlookup() and nlookup_done().

nlookup() Lookup a path.  Unlike the old namei/lookup
code the new lookup code does not do any
fancy pre-disposition of the cache for
create/delete, it simply looks up the requested
path and returns the appropriate locked
namecache pointer.  The caller can obtain the
vnode and directory vnode, as applicable, from
the one namecache structure that is returned.

Access checks are done on directories leading
up to the result but not done on the returned
namecache node.

nlookup_done() Mandatory routine to cleanup a nlookupdata
structure after it has been initialized and
all operations have been completed on it.

nlookup_simple() (in progress) all-in-one wrapped new lookup.

nlookup_mp() helper call for resolving a mount point's
glue NCP.  hackish, will be cleaned up later.

nreadsymlink() helper call to resolve a symlink.  Note that
the namecache does not yet cache symlink data
but the intention is to eventually do so to
avoid having to do VFS ops to get the data.

naccess() Perform access checks on a namecache node
given a mode and cred.

naccess_va() Perform access cheks on a vattr given a
mode and cred.

Begin switching VFS operations from using namei to using nlookup.
In this batch:

* mount  (install mnt_ncp for cross-mount-point handling in
nlookup, simplify the vfs_mount() API to no longer
pass a nameidata structure)
* [l]stat (use nlookup)
* [f]chdir (use nlookup, use recorded f_ncp)
* [f]chroot (use nlookup, use recorded f_ncp)

54 files changed:
sys/bus/usb/usb_port.h
sys/emulation/43bsd/43bsd_stats.c
sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c
sys/emulation/linux/linux_file.c
sys/emulation/linux/linux_stats.c
sys/emulation/svr4/svr4_misc.c
sys/kern/init_main.c
sys/kern/kern_descrip.c
sys/kern/vfs_cache.c
sys/kern/vfs_conf.c
sys/kern/vfs_default.c
sys/kern/vfs_lookup.c
sys/kern/vfs_nlookup.c
sys/kern/vfs_syscalls.c
sys/kern/vfs_vopops.c
sys/sys/file.h
sys/sys/kern_syscall.h
sys/sys/mount.h
sys/sys/namecache.h
sys/sys/nlookup.h
sys/sys/systm.h
sys/sys/vfsops.h
sys/sys/vnode.h
sys/vfs/coda/coda_vfsops.c
sys/vfs/coda/coda_vfsops.h
sys/vfs/fdesc/fdesc_vfsops.c
sys/vfs/gnu/ext2fs/ext2_lookup.c
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/hpfs/hpfs_vnops.c
sys/vfs/isofs/cd9660/cd9660_lookup.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/msdosfs/msdosfs_lookup.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/nfs/nfs_vfsops.c
sys/vfs/nfs/nfs_vnops.c
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/ntfs/ntfs_vnops.c
sys/vfs/nullfs/null_vfsops.c
sys/vfs/nwfs/nwfs_io.c
sys/vfs/nwfs/nwfs_vfsops.c
sys/vfs/nwfs/nwfs_vnops.c
sys/vfs/portal/portal_vfsops.c
sys/vfs/procfs/procfs_vfsops.c
sys/vfs/smbfs/smbfs_io.c
sys/vfs/smbfs/smbfs_vfsops.c
sys/vfs/smbfs/smbfs_vnops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/udf/udf_vnops.c
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_lookup.c
sys/vfs/umapfs/umap_vfsops.c
sys/vfs/union/union_vfsops.c

index e9179f2..c39408c 100644 (file)
@@ -2,7 +2,7 @@
  * $OpenBSD: usb_port.h,v 1.18 2000/09/06 22:42:10 rahnds Exp $
  * $NetBSD: usb_port.h,v 1.54 2002/03/28 21:49:19 ichiro Exp $
  * $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.65 2003/11/09 23:54:21 joe Exp $
- * $DragonFly: src/sys/bus/usb/usb_port.h,v 1.10 2004/08/23 16:03:44 joerg Exp $
+ * $DragonFly: src/sys/bus/usb/usb_port.h,v 1.11 2004/09/30 18:59:14 dillon Exp $
  */
 
 /* Also already merged from NetBSD:
index a3cb46b..8fc436f 100644 (file)
@@ -37,7 +37,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/emulation/43bsd/43bsd_stats.c,v 1.2 2003/11/03 15:57:33 daver Exp $
+ * $DragonFly: src/sys/emulation/43bsd/43bsd_stats.c,v 1.3 2004/09/30 18:59:35 dillon Exp $
  *     from: DragonFly kern/kern_descrip.c,v 1.16
  *     from: DragonFly kern/vfs_syscalls.c,v 1.21
  *
@@ -55,6 +55,7 @@
 #include <sys/stat.h>
 #include <sys/kern_syscall.h>
 #include <sys/namei.h>
+#include <sys/nlookup.h>
 
 static int
 compat_43_copyout_stat(struct stat *st, struct ostat *uaddr)
@@ -101,35 +102,33 @@ ofstat(struct ofstat_args *uap)
 int
 ostat(struct ostat_args *uap)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat st;
        int error;
 
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_USERSPACE, uap->path, td);
-
-       error = kern_stat(&nd, &st);
-
-       if (error == 0)
-               error = compat_43_copyout_stat(&st, uap->ub);
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_stat(&nd, &st);
+               if (error == 0)
+                       error = compat_43_copyout_stat(&st, uap->ub);
+               nlookup_done(&nd);
+       }
        return (error);
 }
 
 int
 olstat(struct olstat_args *uap)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat st;
        int error;
 
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_USERSPACE, uap->path, td);
-
-       error = kern_stat(&nd, &st);
-
-       if (error == 0)
-               error = compat_43_copyout_stat(&st, uap->ub);
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0) {
+               error = kern_stat(&nd, &st);
+               if (error == 0)
+                       error = compat_43_copyout_stat(&st, uap->ub);
+               nlookup_done(&nd);
+       }
        return (error);
 }
index 670b343..83338d1 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.6 2004/08/17 18:57:32 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c,v 1.7 2004/09/30 18:59:41 dillon Exp $
  */
 
 /*
@@ -58,7 +58,7 @@
 extern struct vnodeopv_entry_desc linprocfs_vnodeop_entries[];
 
 static int     linprocfs_mount (struct mount *mp, char *path, caddr_t data,
-                                 struct nameidata *ndp, struct thread *td);
+                                 struct thread *td);
 static int     linprocfs_statfs (struct mount *mp, struct statfs *sbp,
                                   struct thread *td);
 static int     linprocfs_unmount (struct mount *mp, int mntflags,
@@ -71,11 +71,10 @@ static int  linprocfs_unmount (struct mount *mp, int mntflags,
  */
 /* ARGSUSED */
 static int
-linprocfs_mount(mp, path, data, ndp, td)
+linprocfs_mount(mp, path, data, td)
        struct mount *mp;
        char *path;
        caddr_t data;
-       struct nameidata *ndp;
        struct thread *td;
 {
        size_t size;
index 82551c6..776ea65 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_file.c,v 1.41.2.6 2003/01/06 09:19:43 fjoe Exp $
- * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.16 2004/03/01 06:33:15 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.17 2004/09/30 18:59:38 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -43,6 +43,7 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/namei.h>
+#include <sys/nlookup.h>
 #include <sys/proc.h>
 #include <sys/sysproto.h>
 #include <sys/tty.h>
@@ -508,8 +509,7 @@ linux_unlink(struct linux_unlink_args *args)
 int
 linux_chdir(struct linux_chdir_args *args)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        char *path;
        int error;
 
@@ -520,11 +520,11 @@ linux_chdir(struct linux_chdir_args *args)
        if (ldebug(chdir))
                printf(ARGS(chdir, "%s"), path);
 #endif
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_SYSSPACE,
-           path, td);
-
-       error = kern_chdir(&nd);
-
+       error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_chdir(&nd);
+               nlookup_done(&nd);
+       }
        linux_free_path(&path);
        return(error);
 }
index aa8d1db..661dc4c 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_stats.c,v 1.22.2.3 2001/11/05 19:08:23 marcel Exp $
- * $DragonFly: src/sys/emulation/linux/linux_stats.c,v 1.12 2004/05/19 22:52:55 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_stats.c,v 1.13 2004/09/30 18:59:38 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -38,6 +38,7 @@
 #include <sys/proc.h>
 #include <sys/mount.h>
 #include <sys/namei.h>
+#include <sys/nlookup.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
@@ -94,9 +95,8 @@ newstat_copyout(struct stat *buf, void *ubuf)
 int
 linux_newstat(struct linux_newstat_args *args)
 {
-       struct thread *td = curthread;
        struct stat buf;
-       struct nameidata nd;
+       struct nlookupdata nd;
        char *path;
        int error;
 
@@ -107,13 +107,12 @@ linux_newstat(struct linux_newstat_args *args)
        if (ldebug(newstat))
                printf(ARGS(newstat, "%s, *"), path);
 #endif
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_SYSSPACE, path, td);
-
-       error = kern_stat(&nd, &buf);
-
-       if (error == 0)
-               error = newstat_copyout(&buf, args->buf);
+       error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_stat(&nd, &buf);
+               if (error == 0)
+                       error = newstat_copyout(&buf, args->buf);
+       }
        linux_free_path(&path);
        return (error);
 }
@@ -121,9 +120,8 @@ linux_newstat(struct linux_newstat_args *args)
 int
 linux_newlstat(struct linux_newlstat_args *args)
 {
-       struct thread *td = curthread;
        struct stat sb;
-       struct nameidata nd;
+       struct nlookupdata nd;
        char *path;
        int error;
 
@@ -134,13 +132,12 @@ linux_newlstat(struct linux_newlstat_args *args)
        if (ldebug(newlstat))
                printf(ARGS(newlstat, "%s, *"), path);
 #endif
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_SYSSPACE, path, td);
-
-       error = kern_stat(&nd, &sb);
-
-       if (error == 0)
-               error = newstat_copyout(&sb, args->buf);
+       error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
+       if (error == 0) {
+               error = kern_stat(&nd, &sb);
+               if (error == 0)
+                       error = newstat_copyout(&sb, args->buf);
+       }
        linux_free_path(&path);
        return (error);
 }
@@ -365,8 +362,7 @@ stat64_copyout(struct stat *buf, void *ubuf)
 int
 linux_stat64(struct linux_stat64_args *args)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat buf;
        char *path;
        int error;
@@ -378,13 +374,12 @@ linux_stat64(struct linux_stat64_args *args)
        if (ldebug(stat64))
                printf(ARGS(stat64, "%s, *"), path);
 #endif
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ,
-               UIO_SYSSPACE, path, td);
-
-       error = kern_stat(&nd, &buf);
-
-       if (error == 0)
-               error = stat64_copyout(&buf, args->statbuf);
+       error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_stat(&nd, &buf);
+               if (error == 0)
+                       error = stat64_copyout(&buf, args->statbuf);
+       }
        linux_free_path(&path);
        return (error);
 }
@@ -392,8 +387,7 @@ linux_stat64(struct linux_stat64_args *args)
 int
 linux_lstat64(struct linux_lstat64_args *args)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat sb;
        char *path;
        int error;
@@ -405,13 +399,12 @@ linux_lstat64(struct linux_lstat64_args *args)
        if (ldebug(lstat64))
                printf(ARGS(lstat64, "%s, *"), path);
 #endif
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_SYSSPACE, path, td);
-
-       error = kern_stat(&nd, &sb);
-
-       if (error == 0)
-               error = stat64_copyout(&sb, args->statbuf);
+       error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
+       if (error == 0) {
+               error = kern_stat(&nd, &sb);
+               if (error == 0)
+                       error = stat64_copyout(&sb, args->statbuf);
+       }
        linux_free_path(&path);
        return (error);
 }
index 0f263eb..683046c 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * 
  * $FreeBSD: src/sys/svr4/svr4_misc.c,v 1.13.2.7 2003/01/14 21:33:58 dillon Exp $
- * $DragonFly: src/sys/emulation/svr4/Attic/svr4_misc.c,v 1.23 2004/09/28 00:25:34 dillon Exp $
+ * $DragonFly: src/sys/emulation/svr4/Attic/svr4_misc.c,v 1.24 2004/09/30 18:59:43 dillon Exp $
  */
 
 /*
@@ -610,7 +610,7 @@ svr4_sys_fchroot(struct svr4_sys_fchroot_args *uap)
                return error;
        vp = (struct vnode *) fp->f_data;
        vn_lock(vp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
-       if (vp->v_type != VDIR)
+       if (vp->v_type != VDIR || fp->f_ncp == NULL)
                error = ENOTDIR;
        else
                error = VOP_ACCESS(vp, VEXEC, cred, td);
@@ -623,7 +623,7 @@ svr4_sys_fchroot(struct svr4_sys_fchroot_args *uap)
                cache_drop(fdp->fd_nrdir);
        }
        fdp->fd_rdir = vp;
-       fdp->fd_nrdir = cache_vptoncp(vp);      /* stopgap */
+       fdp->fd_nrdir = cache_hold(fp->f_ncp);  /* stopgap */
        return 0;
 }
 
index ff47152..9d39dfd 100644 (file)
@@ -40,7 +40,7 @@
  *
  *     @(#)init_main.c 8.9 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $
- * $DragonFly: src/sys/kern/init_main.c,v 1.37 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/init_main.c,v 1.38 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include "opt_init_path.h"
@@ -92,7 +92,6 @@ int cmask = CMASK;
 extern struct user *proc0paddr;
 extern int fallback_elf_brand;
 
-struct vnode *rootvp;
 int    boothowto = 0;          /* initialized so that it can be patched */
 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
 
@@ -455,21 +454,25 @@ start_init(void *dummy)
        char *var, *path, *next, *s;
        char *ucp, **uap, *arg0, *arg1;
        struct proc *p;
-       struct namecache *rootncp;
+       struct mount *mp;
+       struct vnode *vp;
 
        p = curproc;
 
        /* Get the vnode for '/'.  Set p->p_fd->fd_cdir to reference it. */
-       if (VFS_ROOT(TAILQ_FIRST(&mountlist), &rootvnode))
+       mp = TAILQ_FIRST(&mountlist);
+       if (VFS_ROOT(mp, &vp))
                panic("cannot find root vnode");
-       p->p_fd->fd_cdir = rootvnode;
+       if (mp->mnt_ncp == NULL)
+               mp->mnt_ncp = cache_allocroot(vp);
+       p->p_fd->fd_cdir = vp;
        vref(p->p_fd->fd_cdir);
-       p->p_fd->fd_rdir = rootvnode;
+       p->p_fd->fd_rdir = vp;
        vref(p->p_fd->fd_rdir);
-       rootncp = vfs_cache_setroot(rootvnode);
-       VOP_UNLOCK(rootvnode, NULL, 0, curthread);
-       p->p_fd->fd_ncdir = cache_hold(rootncp);
-       p->p_fd->fd_nrdir = cache_hold(rootncp);
+       vfs_cache_setroot(vp, cache_hold(mp->mnt_ncp));
+       VOP_UNLOCK(vp, NULL, 0, curthread); /* leave ref intact */
+       p->p_fd->fd_ncdir = cache_hold(mp->mnt_ncp);
+       p->p_fd->fd_nrdir = cache_hold(mp->mnt_ncp);
 
        /*
         * Need just enough stack to hold the faked-up "execve()" arguments.
index 1952cf1..afd79cd 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)kern_descrip.c      8.6 (Berkeley) 4/19/94
  * $FreeBSD: src/sys/kern/kern_descrip.c,v 1.81.2.19 2004/02/28 00:43:31 tegge Exp $
- * $DragonFly: src/sys/kern/kern_descrip.c,v 1.28 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_descrip.c,v 1.29 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -952,6 +952,10 @@ ffree(struct file *fp)
        KASSERT((fp->f_count == 0), ("ffree: fp_fcount not 0!"));
        LIST_REMOVE(fp, f_list);
        crfree(fp->f_cred);
+       if (fp->f_ncp) {
+           cache_drop(fp->f_ncp);
+           fp->f_ncp = NULL;
+       }
        nfiles--;
        free(fp, M_FILE);
 }
index c036886..4039372 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.28 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_cache.c,v 1.29 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -110,10 +110,6 @@ MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
 
 static LIST_HEAD(nchashhead, namecache) *nchashtbl;    /* Hash Table */
 static struct namecache_list   ncneglist;              /* instead of vnode */
-static struct namecache                rootnamecache;          /* Dummy node */
-
-static int     nczapcheck;             /* panic on bad release */
-SYSCTL_INT(_debug, OID_AUTO, nczapcheck, CTLFLAG_RW, &nczapcheck, 0, "");
 
 static u_long  nchash;                 /* size of hash table */
 SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0, "");
@@ -220,6 +216,10 @@ cache_link_parent(struct namecache *ncp, struct namecache *par)
        ncp->nc_parent = par;
        if (TAILQ_EMPTY(&par->nc_list)) {
                TAILQ_INSERT_HEAD(&par->nc_list, ncp, nc_entry);
+               /*
+                * Any vp associated with an ncp which has children must
+                * be held.
+                */
                if (par->nc_vp)
                        vhold(par->nc_vp);
        } else {
@@ -278,7 +278,9 @@ cache_drop(struct namecache *ncp)
 
 /*
  * Namespace locking.  The caller must already hold a reference to the
- * namecache structure in order to lock/unlock it.  
+ * namecache structure in order to lock/unlock it.  This function prevents
+ * the namespace from being created or destroyed by accessors other then
+ * the lock holder.
  *
  * Note that holding a locked namecache structure does not prevent the
  * underlying vnode from being destroyed and the namecache state moving
@@ -305,14 +307,14 @@ cache_lock(struct namecache *ncp)
                if (tsleep(ncp, 0, "clock", hz) == EWOULDBLOCK) {
                        if (didwarn == 0) {
                                didwarn = 1;
-                               printf("cache_lock: blocked on %*.*s\n",
+                               printf("[diagnostic] cache_lock: blocked on %*.*s\n",
                                        ncp->nc_nlen, ncp->nc_nlen,
                                        ncp->nc_name);
                        }
                }
        }
        if (didwarn == 1) {
-               printf("cache_lock: unblocked %*.*s\n",
+               printf("[diagnostic] cache_lock: unblocked %*.*s\n",
                        ncp->nc_nlen, ncp->nc_nlen, ncp->nc_name);
        }
 }
@@ -337,11 +339,12 @@ cache_unlock(struct namecache *ncp)
 /*
  * ref-and-lock, unlock-and-deref functions.
  */
-void
+struct namecache *
 cache_get(struct namecache *ncp)
 {
        _cache_hold(ncp);
        cache_lock(ncp);
+       return(ncp);
 }
 
 void
@@ -351,44 +354,6 @@ cache_put(struct namecache *ncp)
        _cache_drop(ncp);
 }
 
-/*
- * Locate or create a dummy namecache entry for the vnode, reference,
- * and return it.  The namecache entry will be unhashed, unnamed, and not
- * have any parent.
- *
- * This routine is primarily a stopgap to allow us to track the current,
- * root, and jail directories until the whole system is shifted over to
- * the new namecache API.  However, we might need it permanently to handle
- * things like fchdir() and fchroot().
- */
-struct namecache *
-cache_vptoncp(struct vnode *vp)
-{
-       struct namecache *ncp;
-       struct namecache *new_ncp;
-
-       new_ncp = NULL;
-retry:
-       TAILQ_FOREACH(ncp, &vp->v_namecache, nc_vnode) {
-               if (ncp->nc_flag & NCF_UNRESOLVED)
-                       continue;
-               if (ncp->nc_name == NULL && ncp->nc_parent == NULL) {
-                       if (new_ncp)
-                               free(new_ncp, M_VFSCACHE);
-                       goto done;
-               }
-       }
-       if (new_ncp == NULL) {
-               new_ncp = cache_alloc();
-               goto retry;
-       }
-       ncp = new_ncp;
-       cache_setvp(ncp, vp);
-done:
-       cache_hold(ncp);
-       return(ncp);
-}
-
 /*
  * Resolve an unresolved ncp by associating a vnode with it.  If the
  * vnode is NULL, a negative cache entry is created.
@@ -401,24 +366,35 @@ cache_setvp(struct namecache *ncp, struct vnode *vp)
        KKASSERT(ncp->nc_flag & NCF_UNRESOLVED);
        ncp->nc_vp = vp;
        if (vp != NULL) {
+               /*
+                * Any vp associated with an ncp which has children must
+                * be held.
+                */
+               if (!TAILQ_EMPTY(&ncp->nc_list))
+                       vhold(vp);
                TAILQ_INSERT_HEAD(&vp->v_namecache, ncp, nc_vnode);
+
+               /*
+                * Set auxillary flags
+                */
                switch(vp->v_type) {
                case VDIR:
-                   ncp->nc_flag |= NCF_ISDIR;
-                   break;
+                       ncp->nc_flag |= NCF_ISDIR;
+                       break;
                case VLNK:
-                   ncp->nc_flag |= NCF_ISSYMLINK;
-                   /* XXX cache the contents of the symlink */
-                   break;
+                       ncp->nc_flag |= NCF_ISSYMLINK;
+                       /* XXX cache the contents of the symlink */
+                       break;
                default:
-                   break;
+                       break;
                }
                ++numcache;
+               ncp->nc_error = 0;
        } else {
                TAILQ_INSERT_TAIL(&ncneglist, ncp, nc_vnode);
                ++numneg;
+               ncp->nc_error = ENOENT;
        }
-       ncp->nc_error = 0;
        ncp->nc_flag &= ~NCF_UNRESOLVED;
 }
 
@@ -452,6 +428,85 @@ cache_setunresolved(struct namecache *ncp)
        }
 }
 
+/*
+ * vget the vnode associated with the namecache entry.  Resolve the namecache
+ * entry if necessary and deal with namecache/vp races.  The passed ncp must
+ * be referenced and may be locked.  The ncp's ref/locking state is not 
+ * effected by this call.
+ *
+ * lk_type may be LK_SHARED, LK_EXCLUSIVE.  A ref'd, possibly locked
+ * (depending on the passed lk_type) will be returned in *vpp with an error
+ * of 0, or NULL will be returned in *vpp with a non-0 error code.  The
+ * most typical error is ENOENT, meaning that the ncp represents a negative
+ * cache hit and there is no vnode to retrieve, but other errors can occur
+ * too.
+ *
+ * The main race we have to deal with are namecache zaps.  The ncp itself
+ * will not disappear since it is referenced, and it turns out that the
+ * validity of the vp pointer can be checked simply by rechecking the
+ * contents of ncp->nc_vp.
+ */
+int
+cache_vget(struct namecache *ncp, struct ucred *cred,
+          int lk_type, struct vnode **vpp)
+{
+       struct vnode *vp;
+       int error;
+
+again:
+       vp = NULL;
+       if (ncp->nc_flag & NCF_UNRESOLVED) {
+               cache_lock(ncp);
+               error = cache_resolve(ncp, cred);
+               cache_unlock(ncp);
+       } else {
+               error = 0;
+       }
+       if (error == 0 && (vp = ncp->nc_vp) != NULL) {
+               error = vget(vp, NULL, lk_type, curthread);
+               if (error) {
+                       if (vp != ncp->nc_vp)   /* handle cache_zap race */
+                               goto again;
+                       vp = NULL;
+               } else if (vp != ncp->nc_vp) {  /* handle cache_zap race */
+                       vput(vp);
+                       goto again;
+               }
+       }
+       if (error == 0 && vp == NULL)
+               error = ENOENT;
+       *vpp = vp;
+       return(error);
+}
+
+int
+cache_vref(struct namecache *ncp, struct ucred *cred, struct vnode **vpp)
+{
+       struct vnode *vp;
+       int error;
+
+again:
+       vp = NULL;
+       if (ncp->nc_flag & NCF_UNRESOLVED) {
+               cache_lock(ncp);
+               error = cache_resolve(ncp, cred);
+               cache_unlock(ncp);
+       } else {
+               error = 0;
+       }
+       if (error == 0 && (vp = ncp->nc_vp) != NULL) {
+               vref(vp);
+               if (vp != ncp->nc_vp) {         /* handle cache_zap race */
+                       vrele(vp);
+                       goto again;
+               }
+       }
+       if (error == 0 && vp == NULL)
+               error = ENOENT;
+       *vpp = vp;
+       return(error);
+}
+
 /*
  * Try to destroy a namecache entry.  The entry is disassociated from its
  * vnode or ncneglist and reverted to an UNRESOLVED state.
@@ -499,13 +554,6 @@ cache_zap(struct namecache *ncp)
                if (!TAILQ_EMPTY(&ncp->nc_list))
                        goto done;
 
-               /*
-                * Ok, we can completely destroy and free this entry.  Sanity
-                * check it against our static rootnamecache structure,
-                * then remove it from the hash.
-                */
-               KKASSERT(ncp != &rootnamecache);
-
                if (ncp->nc_flag & NCF_HASHED) {
                        ncp->nc_flag &= ~NCF_HASHED;
                        LIST_REMOVE(ncp, nc_hash);
@@ -578,28 +626,6 @@ cache_nlookup(struct namecache *par, struct nlcomponent *nlc)
        numcalls++;
        gd = mycpu;
 
-       /*
-        * Deal with "." and "..".  Note that 'par' is not locked, so the
-        * ".." case can simply locate the parent without having to do
-        * anything special.
-        */
-       if (nlc->nlc_nameptr[0] == '.') {
-               if (nlc->nlc_namelen == 1) {
-                       ++dothits;
-                       ++numposhits;
-                       ncp = par;
-                       goto found;
-               }
-               if (nlc->nlc_namelen == 2 && nlc->nlc_nameptr[1] == '.') {
-                       if (par->nc_parent == NULL)
-                               return (NULL);  /* XXX do not return null */
-                       ++dotdothits;
-                       ++numposhits;
-                       ncp = par->nc_parent;
-                       goto found;
-               }
-       }
-
        /*
         * Try to locate an existing entry
         */
@@ -673,16 +699,35 @@ found:
 }
 
 /*
- * Resolve an unresolved namecache entry, generally by looking it up
+ * Resolve an unresolved namecache entry, generally by looking it up.
+ * The passed ncp must be locked. 
+ *
+ * Theoretically since a vnode cannot be recycled while held, and since
+ * the nc_parent chain holds its vnode as long as children exist, the
+ * direct parent of the cache entry we are trying to resolve should
+ * have a valid vnode.  If not then generate an error that we can 
+ * determine is related to a resolver bug.
  */
 int
-cache_resolve(struct namecache *ncp)
+cache_resolve(struct namecache *ncp, struct ucred *cred)
 {
-       panic("cache_resolve() not yet implemented");
+       struct namecache *par;
+
+       if ((par = ncp->nc_parent) == NULL) {
+               ncp->nc_error = EXDEV;
+       } else if (par->nc_vp == NULL) {
+               ncp->nc_error = EXDEV;
+       } else {
+               ncp->nc_error = vop_resolve(par->nc_vp->v_ops, ncp, cred);
+       }
+       return(ncp->nc_error);
 }
 
 /*
- * Lookup an entry in the cache
+ * Lookup an entry in the cache.
+ *
+ * XXX OLD API ROUTINE!  WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
+ * WILL BE REMOVED.
  *
  * Lookup is called with dvp pointing to the directory to search,
  * cnp pointing to the name of the entry being sought. 
@@ -695,14 +740,16 @@ cache_resolve(struct namecache *ncp)
  *
  * If the lookup fails, a status of zero is returned.
  *
- * Note that UNRESOLVED entries are ignored.  They are not negative cache
- * entries.
+ * Matching UNRESOLVED entries are resolved.
+ *
+ * HACKS: we create dummy nodes for parents
  */
 int
 cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 {
        struct namecache *ncp;
        struct namecache *par;
+       struct namecache *bpar;
        u_int32_t hash;
        globaldata_t gd = mycpu;
 
@@ -717,9 +764,12 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
         * NOTE: in this stage of development, the passed 'par' is
         * almost always NULL.
         */
-       if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL) {
+       while ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL) {
                par = cache_alloc();
-               cache_setvp(par, dvp);
+               if (TAILQ_FIRST(&dvp->v_namecache) != NULL)
+                       free(par, M_VFSCACHE);
+               else
+                       cache_setvp(par, dvp); /* XXX par not locked */
        }
 
        /*
@@ -752,17 +802,11 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
         * Try to locate an existing entry
         */
        hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT);
-       hash = fnv_32_buf(&par, sizeof(par), hash);
-       if (nczapcheck > 1)
-           printf("DVP %p/%p %08x %*.*s\n", dvp, par, hash, (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr);
+       bpar = par;
+       hash = fnv_32_buf(&bpar, sizeof(bpar), hash);
 restart:
        LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
                numchecks++;
-               if (nczapcheck > 1) {
-                   printf("TEST ncp par=%p %*.*s\n",
-                       ncp->nc_parent, ncp->nc_nlen, ncp->nc_nlen,
-                       ncp->nc_name);
-               }
 
                /*
                 * Zap entries that have timed out.
@@ -770,28 +814,32 @@ restart:
                if (ncp->nc_timeout && 
                    (int)(ncp->nc_timeout - ticks) < 0
                ) {
-                       if (nczapcheck > 1)
-                           printf("TIMEOUT\n");
                        cache_zap(cache_hold(ncp));
                        goto restart;
                }
 
                /*
-                * Break out if we find a matching entry.  UNRESOLVED entries
-                * never match (they are in the middle of being destroyed).
+                * Break out if we find a matching entry.
                 */
-               if ((ncp->nc_flag & NCF_UNRESOLVED) == 0 &&
-                   ncp->nc_parent == par &&
+               if (ncp->nc_parent == par &&
                    ncp->nc_nlen == cnp->cn_namelen &&
                    bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen) == 0
                ) {
-                       if (nczapcheck > 1)
-                           printf("GOOD\n");
                        cache_hold(ncp);
                        break;
                }
        }
 
+       /*
+        * We found an entry but it is unresolved, act the same as if we
+        * failed to locate the entry.  cache_enter() will do the right
+        * thing.
+        */
+       if (ncp && (ncp->nc_flag & NCF_UNRESOLVED)) {
+               cache_drop(ncp);
+               ncp = NULL;
+       }
+
        /*
         * If we failed to locate an entry, return 0 (indicates failure).
         */
@@ -802,11 +850,6 @@ restart:
                        nummiss++;
                }
                gd->gd_nchstats->ncs_miss++;
-               if (nczapcheck) {
-                   printf("MISS %p/%p %*.*s/%*.*s\n", dvp, par, 
-                       par->nc_nlen, par->nc_nlen, (par->nc_name ? par->nc_name : ""),
-                       (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr);
-               }
                return (0);
        }
 
@@ -860,84 +903,34 @@ restart:
 }
 
 /*
- * Generate a special linkage between the mount point and the root of the 
- * mounted filesystem in order to maintain the namecache topology across
- * a mount point.  The special linkage has a 0-length name component
- * and sets NCF_MOUNTPT.
+ * Add an entry to the cache.  (OLD API)
+ *
+ * XXX OLD API ROUTINE!  WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
+ * WILL BE REMOVED.
  */
 void
-cache_mount(struct vnode *dvp, struct vnode *tvp)
+cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
 {
-       struct namecache *ncp;
        struct namecache *par;
-       struct nchashhead *nchpp;
-       u_int32_t hash;
-
-       /*
-        * If a linkage already exists we do not have to do anything.
-        */
-       hash = fnv_32_buf("", 0, FNV1_32_INIT);
-       hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash);
-       LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
-               numchecks++;
-               if (ncp->nc_vp == tvp &&
-                   ncp->nc_nlen == 0 &&
-                   ncp->nc_parent &&
-                   ncp->nc_parent->nc_vp == dvp 
-               ) {
-                       return;
-               }
-       }
-
-       /* 
-        * XXX
-        */
-       if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL) {
-               par = cache_alloc();
-               cache_setvp(par, dvp);
-       }
-
-       /*
-        * Otherwise create a new linkage.
-        */
-       ncp = cache_alloc();
-       ncp->nc_flag |= NCF_MOUNTPT;
-       cache_setvp(ncp, tvp);
-       cache_link_parent(ncp, par);
-
-       /*
-        * Hash table
-        */
-       hash = fnv_32_buf("", 0, FNV1_32_INIT);
-       hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash);
-       nchpp = NCHHASH(hash);
-       LIST_INSERT_HEAD(nchpp, ncp, nc_hash);
-
-       ncp->nc_flag |= NCF_HASHED;
-}
-
-/*
- * Add an entry to the cache.
- */
-void
-cache_enter(struct vnode *dvp, struct namecache *par, struct vnode *vp, struct componentname *cnp)
-{
        struct namecache *ncp;
+       struct namecache *new_ncp;
        struct namecache *bpar;
        struct nchashhead *nchpp;
        u_int32_t hash;
-       char *name;
 
        /*
         * If the directory has no namecache entry we must associate one with
-        * it.  The name of the entry is not known so it isn't hashed.
+        * it.  The name of the entry is not known so it isn't hashed.  This
+        * is a severe hack to support the old API.
         */
-       if (par == NULL) {
-               if ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL) {
-                       par = cache_alloc();
+       while ((par = TAILQ_FIRST(&dvp->v_namecache)) == NULL) {
+               par = cache_alloc();
+               if (TAILQ_FIRST(&dvp->v_namecache) != NULL)
+                       free(par, M_VFSCACHE);
+               else
                        cache_setvp(par, dvp);
-               }
        }
+       cache_hold(par);
 
        /*
         * This may be a bit confusing.  "." and ".." are 'virtual' entries.
@@ -948,8 +941,10 @@ cache_enter(struct vnode *dvp, struct namecache *par, struct vnode *vp, struct c
         * correct (as might occur when a subdirectory is renamed).
         */
 
-       if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')
+       if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
+               cache_drop(par);
                return;
+       }
        if (cnp->cn_namelen == 2 && cnp->cn_nameptr[0] == '.' &&
            cnp->cn_nameptr[1] == '.'
        ) {
@@ -957,24 +952,32 @@ cache_enter(struct vnode *dvp, struct namecache *par, struct vnode *vp, struct c
                        if (par->nc_parent)
                                cache_unlink_parent(par);
                } else {
-                       if ((ncp = TAILQ_FIRST(&vp->v_namecache)) == NULL) {
+                       while ((ncp = TAILQ_FIRST(&vp->v_namecache)) == NULL) {
                                ncp = cache_alloc();
-                               cache_setvp(ncp, vp);
+                               if (TAILQ_FIRST(&vp->v_namecache) != NULL)
+                                       free(ncp, M_VFSCACHE);
+                               else
+                                       cache_setvp(ncp, vp);
                        }
-                       cache_hold(par);
+                       /*
+                        * ncp is the new parent of par
+                        */
+                       cache_hold(ncp);
                        if (par->nc_parent)
                                cache_unlink_parent(par);
-                       cache_link_parent(par, ncp); /* ncp is parent of par */
-                       cache_drop(par);
+                       cache_link_parent(par, ncp);
+                       cache_drop(ncp);
                }
+               cache_drop(par);
                return;
        }
 
        /*
         * Locate other entries associated with this vnode and zap them,
         * because the purge code may not be able to find them due to
-        * the topology not yet being consistent.  This is a temporary
-        * hack.
+        * the topology not yet being consistent.  This is a hack (this
+        * whole routine is a hack, actually, so that makes this a hack
+        * inside a hack).
         */
        if (vp) {
 again:
@@ -986,19 +989,53 @@ again:
                }
        }
 
+       /*
+        * Try to find a match in the hash table, allocate a new entry if
+        * we can't.  We have to retry the loop after any potential blocking
+        * situation.
+        */
        hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT);
        bpar = par;
        hash = fnv_32_buf(&bpar, sizeof(bpar), hash);
 
-       if (nczapcheck > 1)
-           printf("ENTER %p/%p %08x '%*.*s' %p ", dvp, par, hash, (int)cnp->cn_namelen, (int)cnp->cn_namelen, cnp->cn_nameptr, vp);
-
+       new_ncp = NULL;
+againagain:
+       LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
+               numchecks++;
 
-       name = malloc(cnp->cn_namelen, M_VFSCACHE, M_WAITOK);
-       ncp = cache_alloc();
+               /*
+                * Break out if we find a matching entry.
+                */
+               if (ncp->nc_parent == par &&
+                   ncp->nc_nlen == cnp->cn_namelen &&
+                   bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen) == 0
+               ) {
+                       cache_hold(ncp);
+                       break;
+               }
+       }
+       if (ncp == NULL) {
+               if (new_ncp == NULL) {
+                       new_ncp = cache_alloc();
+                       new_ncp->nc_name = malloc(cnp->cn_namelen, 
+                                               M_VFSCACHE, M_WAITOK);
+                       goto againagain;
+               }
+               ncp = new_ncp;
+               cache_hold(ncp);
+               ncp->nc_nlen = cnp->cn_namelen;
+               bcopy(cnp->cn_nameptr, ncp->nc_name, cnp->cn_namelen);
+               nchpp = NCHHASH(hash);
+               LIST_INSERT_HEAD(nchpp, ncp, nc_hash);
+               ncp->nc_flag |= NCF_HASHED;
+               cache_link_parent(ncp, par);
+       } else if (new_ncp) {
+               free(new_ncp->nc_name, M_VFSCACHE);
+               free(new_ncp, M_VFSCACHE);
+       }
+       cache_drop(par);
+       cache_setunresolved(ncp);
        cache_setvp(ncp, vp);
-       if (nczapcheck > 1)
-           printf("alloc\n");
 
        /*
         * Set a timeout
@@ -1008,22 +1045,6 @@ again:
                        ncp->nc_timeout = 1;
        }
 
-       /*
-        * Linkup the parent pointer, bump the parent vnode's hold
-        * count when we go from 0->1 children.  
-        */
-       cache_link_parent(ncp, par);
-
-       /*
-        * Add to the hash table
-        */
-       ncp->nc_name = name;
-       ncp->nc_nlen = cnp->cn_namelen;
-       bcopy(cnp->cn_nameptr, ncp->nc_name, cnp->cn_namelen);
-       nchpp = NCHHASH(hash);
-       LIST_INSERT_HEAD(nchpp, ncp, nc_hash);
-       ncp->nc_flag |= NCF_HASHED;
-
        /*
         * If the target vnode is NULL if this is to be a negative cache
         * entry.
@@ -1033,6 +1054,7 @@ again:
                if (cnp->cn_flags & CNP_ISWHITEOUT)
                        ncp->nc_flag |= NCF_WHITEOUT;
        }
+       cache_drop(ncp);
 
        /*
         * Don't cache too many negative hits
@@ -1046,8 +1068,6 @@ again:
 
 /*
  * Name cache initialization, from vfsinit() when we are booting
- *
- * rootnamecache is initialized such that it cannot be recursively deleted.
  */
 void
 nchinit(void)
@@ -1063,9 +1083,20 @@ nchinit(void)
        
        TAILQ_INIT(&ncneglist);
        nchashtbl = hashinit(desiredvnodes*2, M_VFSCACHE, &nchash);
-       TAILQ_INIT(&rootnamecache.nc_list);
-       rootnamecache.nc_flag |= NCF_HASHED | NCF_ROOT | NCF_UNRESOLVED;
-       rootnamecache.nc_refs = 1;
+}
+
+/*
+ * Called from start_init() to bootstrap the root filesystem.  Returns
+ * a referenced, unlocked namecache record.
+ */
+struct namecache *
+cache_allocroot(struct vnode *vp)
+{
+       struct namecache *ncp = cache_alloc();
+
+       cache_setvp(ncp, vp);
+       ncp->nc_flag |= NCF_MOUNTPT | NCF_ROOT;
+       return(cache_hold(ncp));
 }
 
 /*
@@ -1078,25 +1109,21 @@ nchinit(void)
  *     If the caller intends to save the returned namecache pointer somewhere
  *     it must cache_hold() it.
  */
-struct namecache *
-vfs_cache_setroot(struct vnode *nvp)
+void
+vfs_cache_setroot(struct vnode *nvp, struct namecache *ncp)
 {
-       KKASSERT(rootnamecache.nc_refs > 0);    /* don't accidently free */
-       cache_zap(cache_hold(&rootnamecache));
-
-       rootnamecache.nc_vp = nvp;
-       rootnamecache.nc_flag &= ~NCF_UNRESOLVED;
-       if (nvp) {
-               ++numcache;
-               if (!TAILQ_EMPTY(&rootnamecache.nc_list))
-                       vhold(nvp);
-               TAILQ_INSERT_HEAD(&nvp->v_namecache, &rootnamecache, nc_vnode);
-       } else {
-               ++numneg;
-               TAILQ_INSERT_TAIL(&ncneglist, &rootnamecache, nc_vnode);
-               rootnamecache.nc_flag &= ~NCF_WHITEOUT;
-       }
-       return(&rootnamecache);
+       struct vnode *ovp;
+       struct namecache *oncp;
+
+       ovp = rootvnode;
+       oncp = rootncp;
+       rootvnode = nvp;
+       rootncp = ncp;
+
+       if (ovp)
+               vrele(ovp);
+       if (oncp)
+               cache_drop(oncp);
 }
 
 /*
index 2a638c6..fb6f9d0 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/kern/vfs_conf.c,v 1.49.2.5 2003/01/07 11:56:53 joerg Exp $
- *     $DragonFly: src/sys/kern/vfs_conf.c,v 1.11 2004/07/20 03:08:23 dillon Exp $
+ *     $DragonFly: src/sys/kern/vfs_conf.c,v 1.12 2004/09/30 18:59:48 dillon Exp $
  */
 
 /*
@@ -58,6 +58,7 @@
 #include <sys/conf.h>
 #include <sys/cons.h>
 #include <sys/device.h>
+#include <sys/namecache.h>
 #include <sys/paths.h>
 
 #include "opt_ddb.h"
@@ -70,6 +71,7 @@ MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
 #define ROOTNAME       "root_device"
 
 struct vnode   *rootvnode;
+struct namecache *rootncp;
 
 /* 
  * The root specifiers we will try if RB_CDROM is specified.  Note that
@@ -233,7 +235,7 @@ vfs_mountroot_try(const char *mountfrom)
                mp->mnt_flag &= ~MNT_RDONLY;
        }
 
-       error = VFS_MOUNT(mp, NULL, NULL, NULL, td);
+       error = VFS_MOUNT(mp, NULL, NULL, td);
 
 done:
        if (vfsname != NULL)
index e607017..c779268 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $
- * $DragonFly: src/sys/kern/vfs_default.c,v 1.14 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_default.c,v 1.15 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -112,9 +112,6 @@ VNODEOP_SET(default_vnodeop_opv_desc);
 int
 vop_eopnotsupp(struct vop_generic_args *ap)
 {
-       /*
-       printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name);
-       */
        return (EOPNOTSUPP);
 }
 
@@ -158,13 +155,21 @@ vop_panic(struct vop_generic_args *ap)
 /*
  * vop_noresolve { struct namecache *a_ncp }   XXX STOPGAP FUNCTION
  *
+ * XXX OLD API ROUTINE!  WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
+ * WILL BE REMOVED.  This procedure exists for all VFSs which have not
+ * yet implemented vop_resolve().  It converts vop_resolve() into a 
+ * vop_lookup() and does appropriate translations.
+ *
  * Resolve a ncp for VFSs which do not support the VOP.  Eventually all
  * VFSs will support this VOP and this routine can be removed, since
  * vop_resolve() is far less complex then the older LOOKUP/CACHEDLOOKUP
  * API.
  *
- * A locked ncp is passed in to be resolved.  An NCP is resolved by
- * calling cache_setvp() on it.  No vnode locks are retained and the
+ * A locked ncp is passed in to be resolved.  The NCP is resolved by
+ * figuring out the vnode (if any) and calling cache_setvp() to attach the
+ * vnode to the entry.  If the entry represents a non-existant node then
+ * cache_setvp() is called with a NULL vnode to resolve the entry into a
+ * negative cache entry.  No vnode locks are retained and the
  * ncp is left locked on return.
  */
 static int
@@ -177,6 +182,8 @@ vop_noresolve(struct vop_resolve_args *ap)
        struct componentname cnp;
 
        ncp = ap->a_ncp;        /* locked namecache node */
+       if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
+               return(EPERM);
        if (ncp->nc_parent == NULL)
                return(EPERM);
        if ((dvp = ncp->nc_parent->nc_vp) == NULL)
@@ -188,13 +195,18 @@ vop_noresolve(struct vop_resolve_args *ap)
        cnp.cn_flags = CNP_ISLASTCN;
        cnp.cn_nameptr = ncp->nc_name;
        cnp.cn_namelen = ncp->nc_nlen;
-       /* creds */
-       /* td */
+       cnp.cn_cred = ap->a_cred;
+       cnp.cn_td = curthread; /* XXX */
+
+       /*
+        * vop_lookup() always returns vp locked.  dvp may or may not be
+        * left locked depending on CNP_PDIRUNLOCK.
+        */
        error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
        if (error == 0) {
                KKASSERT(vp != NULL);
                cache_setvp(ncp, vp);
-               vrele(vp);
+               vput(vp);
        } else if (error == ENOENT) {
                KKASSERT(vp == NULL);
                if (cnp.cn_flags & CNP_ISWHITEOUT)
@@ -205,9 +217,68 @@ vop_noresolve(struct vop_resolve_args *ap)
                vrele(dvp);
        else
                vput(dvp);
-       return(error);
+       return (error);
+}
+
+#if 0
+
+/*
+ * vop_noremove { struct namecache *a_ncp }    XXX STOPGAP FUNCTION
+ *
+ * Remove the file/dir represented by a_ncp.
+ *
+ * XXX ultra difficult.  A number of existing filesystems, including UFS,
+ *     assume that the directory will remain locked and the lookup will
+ *     store the directory offset and other things in the directory inode
+ *     for the later VOP_REMOVE to use.  We have to move all that
+ *     functionality into e.g. UFS's VOP_REMOVE itself.
+ */
+static int
+vop_nonremove(struct vop_nremove_args *ap)
+{
+       struct namecache *ncfile;
+       struct namecache *ncdir;
+       struct componentname cnd;
+       struct vnode *vp;
+       struct vnode *vpd;
+       thread_t td;
+       int error;
+
+       td = curthread;
+       ncfile = ap->a_ncp;
+       ncdir = ncfile->nc_parent;
+
+       if ((error = cache_vget(ncdir, ap->a_cred, LK_EXCLUSIVE, &vpd)) != 0)
+               return (error);
+       if ((error = cache_vget(ncfile, ap->a_cred, LK_EXCLUSIVE, &vp)) != 0) {
+               vput(vpd);
+               return (error);
+       }
+       bzero(&cnd, sizeof(cnd));
+       cnd.cn_nameiop = NAMEI_DELETE;
+       cnd.cn_td = td;
+       cnd.cn_cred = ap->a_cred;
+       cnd.cn_nameptr = ncfile->nc_name;
+       cnd.cn_namelen = ncfile->nc_nlen;
+       error = VOP_REMOVE(vpd, NCPNULL, vp, &cnd);
+       vput(vp);
+       vput(vpd);
+
+       /*
+        * Re-resolve the ncp to match the fact that the file has been
+        * deleted from the namespace.  If an error occured leave the ncp
+        * unresolved (meaning that we have no idea what the correct state
+        * is).
+        */
+       cache_setunresolved(ncfile);
+       if (error == 0)
+               cache_setvp(ncfile, NULL);
+        return (error);
 }
 
+#endif
+
+
 static int
 vop_nolookup(ap)
        struct vop_lookup_args /* {
index 9693abd..9e8ce4c 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_lookup.c        8.4 (Berkeley) 2/16/94
  * $FreeBSD: src/sys/kern/vfs_lookup.c,v 1.38.2.3 2001/08/31 19:36:49 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_lookup.c,v 1.16 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_lookup.c,v 1.17 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include "opt_ktrace.h"
@@ -539,7 +539,6 @@ unionlookup:
                        dpunlocked = 1;
                        goto bad2;
                }
-               cache_mount(dp, tdp);
                vrele(dp);
                ndp->ni_vp = dp = tdp;
        }
index c9e2283..d1c02c2 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/vfs_nlookup.c,v 1.1 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_nlookup.c,v 1.2 2004/09/30 18:59:48 dillon Exp $
  */
 /*
  * nlookup() is the 'new' namei interface.  Rather then return directory and
@@ -63,6 +63,7 @@
 #include <sys/namei.h>
 #include <sys/nlookup.h>
 #include <sys/malloc.h>
+#include <sys/stat.h>
 #include <vm/vm_zone.h>
 
 #ifdef KTRACE
@@ -74,8 +75,8 @@
  * or a degenerate empty string (which is not allowed).
  */
 int
-nlookup_init(struct nlookupdata *nd, const char *path, enum uio_seg seg, 
-               int flags)
+nlookup_init(struct nlookupdata *nd, 
+            const char *path, enum uio_seg seg, int flags)
 {
     size_t pathlen;
     struct proc *p;
@@ -104,18 +105,19 @@ nlookup_init(struct nlookupdata *nd, const char *path, enum uio_seg seg,
        error = ENOENT;
 
     if (error == 0) {
-       if (p->p_fd) {
+       if (p && p->p_fd) {
            nd->nl_ncp = cache_hold(p->p_fd->fd_ncdir);
            nd->nl_rootncp = cache_hold(p->p_fd->fd_nrdir);
            if (p->p_fd->fd_njdir)
                nd->nl_jailncp = cache_hold(p->p_fd->fd_njdir);
+           nd->nl_cred = crhold(p->p_ucred);
        } else {
-           nd->nl_ncp = cache_vptoncp(rootvnode);
+           nd->nl_ncp = cache_hold(rootncp);
            nd->nl_rootncp = cache_hold(nd->nl_ncp);
            nd->nl_jailncp = cache_hold(nd->nl_ncp);
+           nd->nl_cred = crhold(proc0.p_ucred);
        }
        nd->nl_td = td;
-       nd->nl_cred = crhold(p->p_ucred);
        nd->nl_flags |= flags;
     } else {
        nlookup_done(nd);
@@ -124,12 +126,20 @@ nlookup_init(struct nlookupdata *nd, const char *path, enum uio_seg seg,
 }
 
 /*
- * Cleanup a nlookupdata structure after we are through with it.
+ * Cleanup a nlookupdata structure after we are through with it.  This may
+ * be called on any nlookupdata structure initialized with nlookup_init().
+ * Calling nlookup_done() is mandatory in all cases except where nlookup_init()
+ * returns an error, even if as a consumer you believe you have taken all
+ * dynamic elements out of the nlookupdata structure.
  */
 void
 nlookup_done(struct nlookupdata *nd)
 {
     if (nd->nl_ncp) {
+       if (nd->nl_flags & NLC_NCPISLOCKED) {
+           nd->nl_flags &= ~NLC_NCPISLOCKED;
+           cache_unlock(nd->nl_ncp);
+       }
        cache_drop(nd->nl_ncp);
        nd->nl_ncp = NULL;
     }
@@ -149,22 +159,32 @@ nlookup_done(struct nlookupdata *nd)
        crfree(nd->nl_cred);
        nd->nl_cred = NULL;
     }
+    nd->nl_flags = 0;
 }
 
 /*
- * Simple all-in-one nlookup
+ * Simple all-in-one nlookup.  Returns a locked namecache structure or NULL
+ * if an error occured. 
+ *
+ * Note that the returned ncp is not checked for permissions, though VEXEC
+ * is checked on the directory path leading up to the result.  The caller
+ * must call naccess() to check the permissions of the returned leaf.
  */
 struct namecache *
-nlookup_simple(const char *str, enum uio_seg seg, int niflags, int *error)
+nlookup_simple(const char *str, enum uio_seg seg,
+              int niflags, int *error)
 {
     struct nlookupdata nd;
     struct namecache *ncp;
 
     *error = nlookup_init(&nd, str, seg, niflags);
     if (*error == 0) {
-           *error = nlookup(&nd);
-           ncp = nd.nl_ncp;    /* keep hold ref from structure */
-           nd.nl_ncp = NULL;   /* and NULL out */
+           if ((*error = nlookup(&nd)) == 0) {
+                   ncp = nd.nl_ncp;    /* keep hold ref from structure */
+                   nd.nl_ncp = NULL;   /* and NULL out */
+           } else {
+                   ncp = NULL;
+           }
            nlookup_done(&nd);
     } else {
            ncp = NULL;
@@ -176,12 +196,17 @@ nlookup_simple(const char *str, enum uio_seg seg, int niflags, int *error)
  * Do a generic nlookup.  Note that the passed nd is not nlookup_done()'d
  * on return, even if an error occurs.  If no error occurs the returned
  * nl_ncp is always referenced and locked, otherwise it may or may not be.
+ *
+ * Intermediate directory elements, including the current directory, require
+ * execute (search) permission.  nlookup does not examine the access 
+ * permissions on the returned element.
  */
 int
 nlookup(struct nlookupdata *nd)
 {
     struct nlcomponent nlc;
     struct namecache *ncp;
+    struct namecache *nct;
     char *ptr;
     int error;
     int len;
@@ -206,7 +231,7 @@ nlookup(struct nlookupdata *nd)
     ptr = nd->nl_path;
 
     /*
-     * Loop on the path compoenents
+     * Loop on the path components
      */
     for (;;) {
        /*
@@ -221,9 +246,21 @@ nlookup(struct nlookupdata *nd)
            } while (*ptr == '/');
            cache_drop(nd->nl_ncp);
            nd->nl_ncp = cache_hold(nd->nl_rootncp);
+           if (*ptr == 0) {
+               cache_lock(nd->nl_ncp);
+               nd->nl_flags |= NLC_NCPISLOCKED;
+               error = 0;
+               break;
+           }
            continue;
        }
 
+       /*
+        * Check directory search permissions
+        */
+       if ((error = naccess(nd->nl_ncp, VEXEC, nd->nl_cred)) != 0)
+           break;
+
        /*
         * Extract the path component
         */
@@ -233,15 +270,47 @@ nlookup(struct nlookupdata *nd)
        nlc.nlc_namelen = ptr - nlc.nlc_nameptr;
 
        /*
-        * Resolve the namespace.  The ncp returned by cache_nlookup()
-        * is referenced and locked.
+        * Lookup the path component in the cache, creating an unresolved
+        * entry if necessary.  We have to handle "." and ".." as special
+        * cases.
+        *
+        * When handling ".." we have to detect a traversal back through a
+        * mount point and skip the mount-under node.  If we are at the root
+        * ".." just returns the root.
+        */
+       if (nlc.nlc_namelen == 1 && nlc.nlc_nameptr[0] == '.') {
+           ncp = cache_get(nd->nl_ncp);
+       } else if (nlc.nlc_namelen == 2 && 
+                  nlc.nlc_nameptr[0] == '.' && nlc.nlc_nameptr[1] == '.') {
+           ncp = nd->nl_ncp;
+           if (ncp == nd->nl_rootncp) {
+               ncp = cache_get(ncp);
+           } else {
+               if (ncp->nc_flag & NCF_MOUNTPT) {
+                   ncp = ncp->nc_parent;
+                   KKASSERT(ncp != NULL && 1);
+               }
+               ncp = ncp->nc_parent;
+               KKASSERT(ncp != NULL && 2);
+               ncp = cache_get(ncp);
+           }
+       } else {
+           ncp = cache_nlookup(nd->nl_ncp, &nlc);
+       }
+
+       /*
+        * Resolve the namespace if necessary.  The ncp returned by
+        * cache_nlookup() is referenced and locked.
         */
-       ncp = cache_nlookup(nd->nl_ncp, &nlc);
        if (ncp->nc_flag & NCF_UNRESOLVED) {
-           error = cache_resolve(ncp);
+           error = cache_resolve(ncp, nd->nl_cred);
        } else {
            error = ncp->nc_error;
        }
+
+       /*
+        * Early completion
+        */
        if (error) {
            cache_put(ncp);
            break;
@@ -256,15 +325,14 @@ nlookup(struct nlookupdata *nd)
            (*ptr || (nd->nl_flags & NLC_FOLLOW))
        ) {
            if (nd->nl_loopcnt++ >= MAXSYMLINKS) {
-                   error = ELOOP;
-                   cache_put(ncp);
-                   break;
-           }
-           error = nreadsymlink(nd, ncp, &nlc);
-           if (error) {
+               error = ELOOP;
                cache_put(ncp);
                break;
            }
+           error = nreadsymlink(nd, ncp, &nlc);
+           cache_put(ncp);
+           if (error)
+               break;
 
            /*
             * Concatenate trailing path elements onto the returned symlink.
@@ -277,7 +345,6 @@ nlookup(struct nlookupdata *nd)
            if (nlc.nlc_namelen == 0 || nlc.nlc_namelen + len >= MAXPATHLEN) {
                error = nlc.nlc_namelen ? ENAMETOOLONG : ENOENT;
                zfree(namei_zone, nlc.nlc_nameptr);
-               cache_put(ncp);
                break;
            }
            bcopy(ptr, nlc.nlc_nameptr + nlc.nlc_namelen, len + 1);
@@ -294,6 +361,45 @@ nlookup(struct nlookupdata *nd)
            continue;
        }
 
+       /*
+        * If the element is a directory and we are crossing a mount point,
+        * retrieve the root of the mounted filesystem from mnt_ncp and
+        * resolve it if necessary.
+        *
+        * XXX mnt_ncp should really be resolved in the mount code.
+        * NOTE!  the normal nresolve() code cannot resolve mount point ncp's!
+        *
+        * XXX NOCROSSMOUNT
+        */
+       while ((ncp->nc_flag & NCF_ISDIR) && ncp->nc_vp->v_mountedhere &&
+               (nd->nl_flags & NLC_NOCROSSMOUNT) == 0
+       ) {
+           struct mount *mp;
+           struct vnode *tdp;
+
+           mp = ncp->nc_vp->v_mountedhere;
+           cache_put(ncp);
+           nct = cache_get(mp->mnt_ncp);
+           ncp = nct;
+
+           if (ncp->nc_flag & NCF_UNRESOLVED) {
+               while (vfs_busy(mp, 0, NULL, nd->nl_td))
+                   ;
+               error = VFS_ROOT(mp, &tdp);
+               vfs_unbusy(mp, nd->nl_td);
+               if (error) {
+                   cache_put(ncp);
+                   break;
+               }
+               cache_setvp(ncp, tdp);
+               vput(tdp);
+           }
+       }
+       if (error) {
+           cache_put(ncp);
+           break;
+       }
+           
        /*
         * Skip any slashes to get to the next element.  If there 
         * are any slashes at all the current element must be a
@@ -343,6 +449,40 @@ nlookup(struct nlookupdata *nd)
     return(error);
 }
 
+/*
+ * Resolve a mount point's glue ncp.  This ncp connects creates the illusion
+ * of continuity in the namecache tree by connecting the ncp related to the
+ * vnode under the mount to the ncp related to the mount's root vnode.
+ *
+ * If no error occured a locked, ref'd ncp is stored in *ncpp.
+ */
+int
+nlookup_mp(struct mount *mp, struct namecache **ncpp)
+{
+    struct namecache *ncp;
+    struct vnode *vp;
+    int error;
+
+    error = 0;
+    ncp = mp->mnt_ncp;
+    cache_get(ncp);
+    if (ncp->nc_flag & NCF_UNRESOLVED) {
+       while (vfs_busy(mp, 0, NULL, curthread))
+           ;
+       error = VFS_ROOT(mp, &vp);
+       vfs_unbusy(mp, curthread);
+       if (error) {
+           cache_put(ncp);
+           ncp = NULL;
+       } else {
+           cache_setvp(ncp, vp);
+           vput(vp);
+       }
+    }
+    *ncpp = ncp;
+    return(error);
+}
+
 /*
  * Read the contents of a symlink, allocate a path buffer out of the
  * namei_zone and initialize the supplied nlcomponent with the result.
@@ -353,6 +493,7 @@ int
 nreadsymlink(struct nlookupdata *nd, struct namecache *ncp, 
                struct nlcomponent *nlc)
 {
+    struct vnode *vp;
     struct iovec aiov;
     struct uio auio;
     int linklen;
@@ -363,7 +504,7 @@ nreadsymlink(struct nlookupdata *nd, struct namecache *ncp,
     nlc->nlc_namelen = 0;
     if (ncp->nc_vp == NULL)
        return(ENOENT);
-    if ((error = vget(ncp->nc_vp, NULL, LK_SHARED, nd->nl_td)) != 0)
+    if ((error = cache_vget(ncp, nd->nl_cred, LK_SHARED, &vp)) != 0)
        return(error);
     cp = zalloc(namei_zone);
     aiov.iov_base = cp;
@@ -375,10 +516,10 @@ nreadsymlink(struct nlookupdata *nd, struct namecache *ncp,
     auio.uio_segflg = UIO_SYSSPACE;
     auio.uio_td = nd->nl_td;
     auio.uio_resid = MAXPATHLEN - 1;
-    error = VOP_READLINK(ncp->nc_vp, &auio, nd->nl_cred);
+    error = VOP_READLINK(vp, &auio, nd->nl_cred);
     if (error)
        goto fail;
-    linklen = MAXPATHLEN - auio.uio_resid;
+    linklen = MAXPATHLEN - 1 - auio.uio_resid;
     if (varsym_enable) {
        linklen = varsymreplace(cp, linklen, MAXPATHLEN - 1);
        if (linklen < 0) {
@@ -389,11 +530,125 @@ nreadsymlink(struct nlookupdata *nd, struct namecache *ncp,
     cp[linklen] = 0;
     nlc->nlc_nameptr = cp;
     nlc->nlc_namelen = linklen;
-    vput(ncp->nc_vp);
+    vput(vp);
     return(0);
 fail:
     zfree(namei_zone, cp);
-    vput(ncp->nc_vp);
+    vput(vp);
     return(error);
 }
 
+/*
+ * Check access [XXX cache vattr!] [XXX quota]
+ *
+ * Generally check the V* access bits from sys/vnode.h.  All specified bits
+ * must pass for this function to return 0.
+ *
+ * If VCREATE is specified and the target ncp represents a non-existant
+ * file or dir, or if VDELETE is specified and the target exists, the parent
+ * directory is checked for VWRITE.  If VEXCL is specified and the target
+ * ncp represents a positive hit, an error is returned.
+ *
+ * If VCREATE is not specified and the target does not exist (negative hit),
+ * ENOENT is returned.  Note that nlookup() does not (and should not) return
+ * ENOENT for non-existant leafs.
+ *
+ * The passed ncp may or may not be locked.  The caller should use a
+ * locked ncp on leaf lookups, especially for VCREATE, VDELETE, and VEXCL
+ * checks.
+ */
+int
+naccess(struct namecache *ncp, int vmode, struct ucred *cred)
+{
+    struct vnode *vp;
+    struct vattr va;
+    int error;
+
+    if (ncp->nc_flag & NCF_UNRESOLVED) {
+       cache_lock(ncp);
+       cache_resolve(ncp, cred);
+       cache_unlock(ncp);
+    }
+    error = ncp->nc_error;
+    if (vmode & (VDELETE|VCREATE|VEXCL)) {
+       if (((vmode & VCREATE) && ncp->nc_vp == NULL) ||
+           ((vmode & VDELETE) && ncp->nc_vp != NULL)
+       ) {
+           if (ncp->nc_parent == NULL)
+               error = EROFS;
+           else
+               error = naccess(ncp->nc_parent, VWRITE, cred);
+       }
+       if ((vmode & VEXCL) && ncp->nc_vp != NULL)
+           error = EEXIST;
+    }
+    if (error == 0) {
+       error = cache_vget(ncp, cred, LK_SHARED, &vp);
+       if (error == ENOENT) {
+           if (vmode & VCREATE)
+               error = 0;
+       } else if (error == 0) {
+           /* XXX cache the va in the namecache or in the vnode */
+           if ((error = VOP_GETATTR(vp, &va, curthread)) == 0) {
+               if ((vmode & VWRITE) && vp->v_mount) {
+                   if (vp->v_mount->mnt_flag & MNT_RDONLY)
+                       error = EROFS;
+               }
+           }
+           vput(vp);
+           if (error == 0)
+               error = naccess_va(&va, vmode, cred);
+       }
+    }
+    return(error);
+}
+
+/*
+ * Check the requested access against the given vattr using cred.
+ */
+int
+naccess_va(struct vattr *va, int vmode, struct ucred *cred)
+{
+    int i;
+
+    /*
+     * Test the immutable bit for files, directories, and softlinks.
+     */
+    if (vmode & (VWRITE|VDELETE)) {
+       if (va->va_type == VDIR || va->va_type == VLNK || va->va_type == VREG) {
+           if (va->va_flags & IMMUTABLE)
+               return (EPERM);
+       }
+    }
+
+    /*
+     * root gets universal access
+     */
+    if (cred->cr_uid == 0)
+       return(0);
+
+    /*
+     * Check owner perms, group perms, and world perms
+     */
+    vmode &= S_IRWXU;
+    if (cred->cr_uid == va->va_uid) {
+       if ((vmode & va->va_mode) != vmode)
+           return(EACCES);
+       return(0);
+    }
+
+    vmode >>= 3;
+    for (i = 0; i < cred->cr_ngroups; ++i) {
+       if (va->va_gid == cred->cr_groups[i]) {
+           if ((vmode & va->va_mode) != vmode)
+               return(EACCES);
+           return(0);
+       }
+    }
+
+    vmode >>= 3;
+    if ((vmode & va->va_mode) != vmode)
+       return(EACCES);
+    return(0);
+}
+
index c1f969c..8ee736e 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.39 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.40 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -58,6 +58,7 @@
 #include <sys/vnode.h>
 #include <sys/proc.h>
 #include <sys/namei.h>
+#include <sys/nlookup.h>
 #include <sys/dirent.h>
 #include <sys/extattr.h>
 #include <sys/kern_syscall.h>
@@ -73,7 +74,7 @@
 #include <sys/file2.h>
 
 static int checkvp_chdir (struct vnode *vn, struct thread *td);
-static void checkdirs (struct vnode *olddp);
+static void checkdirs (struct vnode *olddp, struct namecache *ncp);
 static int chroot_refuse_vdir_fds (struct filedesc *fdp);
 static int getutimes (const struct timeval *, struct timespec *);
 static int setfown (struct vnode *, uid_t, gid_t);
@@ -103,14 +104,16 @@ mount(struct mount_args *uap)
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
        struct vnode *vp;
+       struct namecache *ncp;
        struct mount *mp;
        struct vfsconf *vfsp;
        int error, flag = 0, flag2 = 0;
        struct vattr va;
-       struct nameidata nd;
+       struct nlookupdata nd;
        char fstypename[MFSNAMELEN];
        lwkt_tokref vlock;
        lwkt_tokref ilock;
+       struct nlcomponent nlc;
 
        KKASSERT(p);
        if (p->p_ucred->cr_prison != NULL)
@@ -130,17 +133,45 @@ mount(struct mount_args *uap)
         */
        if (suser(td)) 
                SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+
        /*
-        * Get vnode to be covered
+        * Lookup the requested path and extract the ncp and vnode.
         */
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE,
-           SCARG(uap, path), td);
-       if ((error = namei(&nd)) != 0)
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               if ((error = nlookup(&nd)) == 0) {
+                       if (nd.nl_ncp->nc_vp == NULL)
+                               error = ENOENT;
+               }
+       }
+       if (error) {
+               nlookup_done(&nd);
                return (error);
-       NDFREE(&nd, NDF_ONLY_PNBUF);
-       vp = nd.ni_vp;
+       }
+
+       /*
+        * Extract the locked+refd ncp and cleanup the nd structure
+        */
+       ncp = nd.nl_ncp;
+       nd.nl_ncp = NULL;
+       nlookup_done(&nd);
+
+       /*
+        * now we have the locked ref'd ncp and unreferenced vnode.
+        */
+       vp = ncp->nc_vp;
+       if ((error = vget(vp, NULL, LK_EXCLUSIVE, td)) != 0) {
+               cache_put(ncp);
+               return (error);
+       }
+       cache_unlock(ncp);
+
+       /*
+        * Now we have an unlocked ref'd ncp and a locked ref'd vp
+        */
        if (SCARG(uap, flags) & MNT_UPDATE) {
                if ((vp->v_flag & VROOT) == 0) {
+                       cache_drop(ncp);
                        vput(vp);
                        return (EINVAL);
                }
@@ -153,6 +184,7 @@ mount(struct mount_args *uap)
                 */
                if ((SCARG(uap, flags) & MNT_RELOAD) &&
                    ((mp->mnt_flag & MNT_RDONLY) == 0)) {
+                       cache_drop(ncp);
                        vput(vp);
                        return (EOPNOTSUPP);    /* Needs translation */
                }
@@ -162,16 +194,19 @@ mount(struct mount_args *uap)
                 */
                if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
                    (error = suser(td))) {
+                       cache_drop(ncp);
                        vput(vp);
                        return (error);
                }
                if (vfs_busy(mp, LK_NOWAIT, NULL, td)) {
+                       cache_drop(ncp);
                        vput(vp);
                        return (EBUSY);
                }
                lwkt_gettoken(&vlock, vp->v_interlock);
                if ((vp->v_flag & VMOUNT) != 0 ||
                    vp->v_mountedhere != NULL) {
+                       cache_drop(ncp);
                        lwkt_reltoken(&vlock);
                        vfs_unbusy(mp, td);
                        vput(vp);
@@ -191,34 +226,41 @@ mount(struct mount_args *uap)
        if ((error = VOP_GETATTR(vp, &va, td)) ||
            (va.va_uid != p->p_ucred->cr_uid &&
             (error = suser(td)))) {
+               cache_drop(ncp);
                vput(vp);
                return (error);
        }
        if ((error = vinvalbuf(vp, V_SAVE, td, 0, 0)) != 0) {
+               cache_drop(ncp);
                vput(vp);
                return (error);
        }
        if (vp->v_type != VDIR) {
+               cache_drop(ncp);
                vput(vp);
                return (ENOTDIR);
        }
        if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) {
+               cache_drop(ncp);
                vput(vp);
                return (error);
        }
-       for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+       for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
                if (!strcmp(vfsp->vfc_name, fstypename))
                        break;
+       }
        if (vfsp == NULL) {
                linker_file_t lf;
 
                /* Only load modules for root (very important!) */
                if ((error = suser(td)) != 0) {
+                       cache_drop(ncp);
                        vput(vp);
                        return error;
                }
                error = linker_load_file(fstypename, &lf);
                if (error || lf == NULL) {
+                       cache_drop(ncp);
                        vput(vp);
                        if (lf == NULL)
                                error = ENODEV;
@@ -226,12 +268,14 @@ mount(struct mount_args *uap)
                }
                lf->userrefs++;
                /* lookup again, see if the VFS was loaded */
-               for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+               for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
                        if (!strcmp(vfsp->vfc_name, fstypename))
                                break;
+               }
                if (vfsp == NULL) {
                        lf->userrefs--;
                        linker_file_unload(lf);
+                       cache_drop(ncp);
                        vput(vp);
                        return (ENODEV);
                }
@@ -240,6 +284,7 @@ mount(struct mount_args *uap)
        if ((vp->v_flag & VMOUNT) != 0 ||
            vp->v_mountedhere != NULL) {
                lwkt_reltoken(&vlock);
+               cache_drop(ncp);
                vput(vp);
                return (EBUSY);
        }
@@ -286,7 +331,7 @@ update:
         * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
         * get.  No freeing of cn_pnbuf.
         */
-       error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, td);
+       error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), td);
        if (mp->mnt_flag & MNT_UPDATE) {
                if (mp->mnt_kern_flag & MNTK_WANTRDWR)
                        mp->mnt_flag &= ~MNT_RDONLY;
@@ -301,14 +346,25 @@ update:
                vp->v_flag &= ~VMOUNT;
                lwkt_reltoken(&vlock);
                vrele(vp);
+               cache_drop(ncp);
                return (error);
        }
        vn_lock(vp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
        /*
-        * Put the new filesystem on the mount list after root.
+        * Put the new filesystem on the mount list after root.  The mount
+        * point gets its own mnt_ncp which is a special ncp linking the
+        * vnode-under to the root of the new mount.  The lookup code
+        * detects the mount point going forward and detects the special
+        * mnt_ncp via NCP_MOUNTPT going backwards.
         */
        cache_purge(vp);
        if (!error) {
+               nlc.nlc_nameptr = "";
+               nlc.nlc_namelen = 0;
+               mp->mnt_ncp = cache_nlookup(ncp, &nlc);
+               mp->mnt_ncp->nc_flag |= NCF_MOUNTPT;
+               cache_drop(ncp);
+               /* XXX get the root of the fs and cache_setvp(mnt_ncp...) */
                lwkt_gettoken(&vlock, vp->v_interlock);
                vp->v_flag &= ~VMOUNT;
                vp->v_mountedhere = mp;
@@ -316,7 +372,8 @@ update:
                lwkt_gettoken(&ilock, &mountlist_token);
                TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
                lwkt_reltoken(&ilock);
-               checkdirs(vp);
+               checkdirs(vp, mp->mnt_ncp);
+               cache_unlock(mp->mnt_ncp);      /* leave ref intact */
                VOP_UNLOCK(vp, NULL, 0, td);
                error = vfs_allocate_syncvnode(mp);
                vfs_unbusy(mp, td);
@@ -332,6 +389,7 @@ update:
                mp->mnt_vfc->vfc_refcount--;
                vfs_unbusy(mp, td);
                free(mp, M_MOUNT);
+               cache_drop(ncp);
                vput(vp);
        }
        return (error);
@@ -341,9 +399,13 @@ update:
  * Scan all active processes to see if any of them have a current
  * or root directory onto which the new filesystem has just been
  * mounted. If so, replace them with the new mount point.
+ *
+ * The passed ncp is ref'd and locked (from the mount code) and
+ * must be associated with the vnode representing the root of the
+ * mount point.
  */
 static void
-checkdirs(struct vnode *olddp)
+checkdirs(struct vnode *olddp, struct namecache *ncp)
 {
        struct filedesc *fdp;
        struct vnode *newdp;
@@ -355,6 +417,13 @@ checkdirs(struct vnode *olddp)
        mp = olddp->v_mountedhere;
        if (VFS_ROOT(mp, &newdp))
                panic("mount: lost mount");
+       cache_setvp(ncp, newdp);
+
+       if (rootvnode == olddp) {
+               vref(newdp);
+               vfs_cache_setroot(newdp, cache_hold(ncp));
+       }
+
        FOREACH_PROC_IN_SYSTEM(p) {
                fdp = p->p_fd;
                if (fdp->fd_cdir == olddp) {
@@ -362,22 +431,16 @@ checkdirs(struct vnode *olddp)
                        vref(newdp);
                        fdp->fd_cdir = newdp;
                        cache_drop(fdp->fd_ncdir);
-                       fdp->fd_ncdir = cache_vptoncp(newdp);
+                       fdp->fd_ncdir = cache_hold(ncp);
                }
                if (fdp->fd_rdir == olddp) {
                        vrele(fdp->fd_rdir);
                        vref(newdp);
                        fdp->fd_rdir = newdp;
                        cache_drop(fdp->fd_nrdir);
-                       fdp->fd_nrdir = cache_vptoncp(newdp);
+                       fdp->fd_nrdir = cache_hold(ncp);
                }
        }
-       if (rootvnode == olddp) {
-               vrele(rootvnode);
-               vref(newdp);
-               rootvnode = newdp;
-               vfs_cache_setroot(rootvnode);
-       }
        vput(newdp);
 }
 
@@ -511,6 +574,8 @@ dounmount(struct mount *mp, int flags, struct thread *td)
        if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
                coveredvp->v_mountedhere = NULL;
                vrele(coveredvp);
+               cache_drop(mp->mnt_ncp);
+               mp->mnt_ncp = NULL;
        }
        mp->mnt_vfc->vfc_refcount--;
        if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
@@ -771,9 +836,11 @@ fchdir(struct fchdir_args *uap)
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
        struct filedesc *fdp = p->p_fd;
-       struct vnode *vp, *tdp;
+       struct vnode *vp, *ovp;
        struct mount *mp;
        struct file *fp;
+       struct namecache *ncp, *oncp;
+       struct namecache *nct;
        int error;
 
        if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
@@ -781,49 +848,73 @@ fchdir(struct fchdir_args *uap)
        vp = (struct vnode *)fp->f_data;
        vref(vp);
        vn_lock(vp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
-       if (vp->v_type != VDIR)
+       if (vp->v_type != VDIR || fp->f_ncp == NULL)
                error = ENOTDIR;
        else
                error = VOP_ACCESS(vp, VEXEC, p->p_ucred, td);
-       while (!error && (mp = vp->v_mountedhere) != NULL) {
-               if (vfs_busy(mp, 0, NULL, td))
-                       continue;
-               error = VFS_ROOT(mp, &tdp);
-               vfs_unbusy(mp, td);
-               if (error)
-                       break;
-               vput(vp);
-               vp = tdp;
-       }
        if (error) {
                vput(vp);
                return (error);
        }
-       VOP_UNLOCK(vp, NULL, 0, td);
-       vrele(fdp->fd_cdir);
-       fdp->fd_cdir = vp;
-       fdp->fd_ncdir = cache_vptoncp(vp);
-       return (0);
+       ncp = cache_hold(fp->f_ncp);
+       while (!error && (mp = vp->v_mountedhere) != NULL) {
+               error = nlookup_mp(mp, &nct);
+               if (error == 0) {
+                       cache_unlock(nct);      /* leave ref intact */
+                       vput(vp);
+                       vp = nct->nc_vp;
+                       error = vget(vp, NULL, LK_SHARED, td);
+                       KKASSERT(error == 0);
+                       cache_drop(ncp);
+                       ncp = nct;
+               }
+       }
+       if (error == 0) {
+               ovp = fdp->fd_cdir;
+               oncp = fdp->fd_ncdir;
+               VOP_UNLOCK(vp, NULL, 0, td);    /* leave ref intact */
+               fdp->fd_cdir = vp;
+               fdp->fd_ncdir = ncp;
+               cache_drop(oncp);
+               vrele(ovp);
+       } else {
+               cache_drop(ncp);
+               vput(vp);
+       }
+       return (error);
 }
 
 int
-kern_chdir(struct nameidata *nd)
+kern_chdir(struct nlookupdata *nd)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
        struct filedesc *fdp = p->p_fd;
+       struct vnode *vp, *ovp;
+       struct namecache *oncp;
        int error;
 
-       if ((error = namei(nd)) != 0)
+       if ((error = nlookup(nd)) != 0)
                return (error);
-       if ((error = checkvp_chdir(nd->ni_vp, td)) == 0) {
-               vrele(fdp->fd_cdir);
-               cache_drop(fdp->fd_ncdir);
-               fdp->fd_cdir = nd->ni_vp;
-               fdp->fd_ncdir = cache_vptoncp(nd->ni_vp);       /* stopgap */
-               vref(fdp->fd_cdir);
+       if ((vp = nd->nl_ncp->nc_vp) == NULL)
+               return (ENOENT);
+       if ((error = vget(vp, NULL, LK_SHARED, td)) != 0)
+               return (error);
+
+       error = checkvp_chdir(vp, td);
+       VOP_UNLOCK(vp, NULL, 0, td);
+       if (error == 0) {
+               ovp = fdp->fd_cdir;
+               oncp = fdp->fd_ncdir;
+               cache_unlock(nd->nl_ncp);       /* leave reference intact */
+               fdp->fd_ncdir = nd->nl_ncp;
+               fdp->fd_cdir = vp;
+               cache_drop(oncp);
+               vrele(ovp);
+               nd->nl_ncp = NULL;
+       } else {
+               vrele(vp);
        }
-       NDFREE(nd, ~(NDF_NO_FREE_PNBUF | NDF_NO_VP_PUT));
        return (error);
 }
 
@@ -835,15 +926,14 @@ kern_chdir(struct nameidata *nd)
 int
 chdir(struct chdir_args *uap)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        int error;
 
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE,
-           uap->path, td);
-
-       error = kern_chdir(&nd);
-
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_chdir(&nd);
+               nlookup_done(&nd);
+       }
        return (error);
 }
 
@@ -886,17 +976,17 @@ SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
      &chroot_allow_open_directories, 0, "");
 
 /*
- * Chroot to the specified vnode.  vp must be locked and referenced on
- * call, and will be left locked and referenced on return.  This routine
- * may acquire additional refs on the vnode when associating it with
- * the process's root and/or jail dirs.
+ * chroot to the specified namecache entry.  We obtain the vp from the
+ * namecache data.  The passed ncp must be locked and referenced and will
+ * remain locked and referenced on return.
  */
-int
-kern_chroot(struct vnode *vp)
+static int
+kern_chroot(struct namecache *ncp)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
        struct filedesc *fdp = p->p_fd;
+       struct vnode *vp;
        int error;
 
        /*
@@ -913,22 +1003,30 @@ kern_chroot(struct vnode *vp)
                if ((error = chroot_refuse_vdir_fds(fdp)) != 0)
                        return (error);
        }
+       if ((vp = ncp->nc_vp) == NULL)
+               return (ENOENT);
+
+       if ((error = vget(vp, NULL, LK_SHARED, td)) != 0)
+               return (error);
 
        /*
         * Check the validity of vp as a directory to change to and 
         * associate it with rdir/jdir.
         */
-       if ((error = checkvp_chdir(vp, td)) == 0) {
+       error = checkvp_chdir(vp, td);
+       VOP_UNLOCK(vp, NULL, 0, td);    /* leave reference intact */
+       if (error == 0) {
                vrele(fdp->fd_rdir);
+               fdp->fd_rdir = vp;      /* reference inherited by fd_rdir */
                cache_drop(fdp->fd_nrdir);
-               fdp->fd_rdir = vp;
-               vref(fdp->fd_rdir);
-               fdp->fd_nrdir = cache_vptoncp(vp);
+               fdp->fd_nrdir = cache_hold(ncp);
                if (fdp->fd_jdir == NULL) {
                        fdp->fd_jdir = vp;
                        vref(fdp->fd_jdir);
-                       fdp->fd_njdir = cache_vptoncp(vp);
+                       fdp->fd_njdir = cache_hold(ncp);
                }
+       } else {
+               vrele(vp);
        }
        return (error);
 }
@@ -943,15 +1041,14 @@ int
 chroot(struct chroot_args *uap)
 {
        struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        int error;
 
        KKASSERT(td->td_proc);
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE,
-               SCARG(uap, path), td);
-       if ((error = namei(&nd)) == 0) {
-               error = kern_chroot(nd.ni_vp);
-               NDFREE(&nd, ~(NDF_NO_FREE_PNBUF | NDF_NO_VP_PUT));
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_chroot(nd.nl_ncp);
+               nlookup_done(&nd);
        }
        return (error);
 }
@@ -984,7 +1081,9 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
        int cmode, flags;
        struct file *nfp;
        int type, indx, error;
+       int ndxerror;
        struct flock lf;
+       struct nlookupdata ndx;
 
        if ((oflags & O_ACCMODE) == O_ACCMODE)
                return (EINVAL);
@@ -1000,6 +1099,14 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
         * the descriptor while we are blocked in vn_open()
         */
        fhold(fp);
+
+       /*
+        * XXX temporary hack so we can record the namecache pointer 
+        * associated with an open descriptor.
+        */
+       ndxerror = nlookup_init(&ndx, nd->ni_dirp, nd->ni_segflg,
+           ((nd->ni_cnd.cn_flags & CNP_FOLLOW) ? NLC_FOLLOW : 0));
+
        error = vn_open(nd, flags, cmode);
        if (error) {
                /*
@@ -1017,6 +1124,7 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
                    (error =
                        dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
                        *res = indx;
+                       nlookup_done(&ndx);
                        return (0);
                }
                /*
@@ -1030,6 +1138,7 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
 
                if (error == ERESTART)
                        error = EINTR;
+               nlookup_done(&ndx);
                return (error);
        }
        p->p_dupfd = 0;
@@ -1051,6 +1160,7 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
                vn_close(vp, flags & FMASK, td);
                fdrop(fp, td);
                *res = indx;
+               nlookup_done(&ndx);
                return 0;
        }
 
@@ -1082,6 +1192,7 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
                                fdrop(fp, td);
                        }
                        fdrop(fp, td);
+                       nlookup_done(&ndx);
                        return (error);
                }
                vn_lock(vp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
@@ -1092,6 +1203,26 @@ kern_open(struct nameidata *nd, int oflags, int mode, int *res)
                ("open: vmio vnode has no backing object after vn_open"));
        VOP_UNLOCK(vp, NULL, 0, td);
 
+       /*
+        * If the vp is a directory locate the ncp to store with the file
+        * descriptor.  XXX temporary.  We may eventually wish to do this
+        * permanently as it would provide an invaluable diagnostic tool,
+        * but first the entire open path needs to be converted from
+        * namei to nlookup so we can avoid having to do a double-lookup.
+        *
+        * The primary purpose of storing the ncp with the file pointer is
+        * so it can be used in fchdir() and fchroot() syscalls, allowing
+        * us to retain an unbroken namecache topology.
+        */
+       if (ndxerror == 0 && vp->v_type == VDIR) {
+               if ((ndxerror = nlookup(&ndx)) == 0) {
+                       fp->f_ncp = ndx.nl_ncp;
+                       ndx.nl_ncp = NULL;
+                       cache_unlock(fp->f_ncp);
+               }
+       }
+       nlookup_done(&ndx);
+
        /*
         * release our private reference, leaving the one associated with the
         * descriptor table intact.
@@ -1622,17 +1753,22 @@ access(struct access_args *uap)
 }
 
 int
-kern_stat(struct nameidata *nd, struct stat *st)
+kern_stat(struct nlookupdata *nd, struct stat *st)
 {
-       struct thread *td = curthread;
        int error;
+       struct vnode *vp;
+       thread_t td;
 
-       error = namei(nd);
-       if (error)
+       if ((error = nlookup(nd)) != 0)
                return (error);
-       error = vn_stat(nd->ni_vp, st, td);
-       NDFREE(nd, NDF_ONLY_PNBUF);
-       vput(nd->ni_vp);
+       if ((vp = nd->nl_ncp->nc_vp) == NULL)
+               return (ENOENT);
+
+       td = curthread;
+       if ((error = vget(vp, NULL, LK_SHARED, td)) != 0)
+               return (error);
+       error = vn_stat(vp, st, td);
+       vput(vp);
        return (error);
 }
 
@@ -1644,18 +1780,17 @@ kern_stat(struct nameidata *nd, struct stat *st)
 int
 stat(struct stat_args *uap)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat st;
        int error;
 
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_USERSPACE, uap->path, td);
-
-       error = kern_stat(&nd, &st);
-
-       if (error == 0)
-               error = copyout(&st, uap->ub, sizeof(*uap->ub));
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, NLC_FOLLOW);
+       if (error == 0) {
+               error = kern_stat(&nd, &st);
+               if (error == 0)
+                       error = copyout(&st, uap->ub, sizeof(*uap->ub));
+               nlookup_done(&nd);
+       }
        return (error);
 }
 
@@ -1667,18 +1802,17 @@ stat(struct stat_args *uap)
 int
 lstat(struct lstat_args *uap)
 {
-       struct thread *td = curthread;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct stat st;
        int error;
 
-       NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ,
-           UIO_USERSPACE, SCARG(uap, path), td);
-
-       error = kern_stat(&nd, &st);
-
-       if (error == 0)
-               error = copyout(&st, uap->ub, sizeof(*uap->ub));
+       error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0);
+       if (error == 0) {
+               error = kern_stat(&nd, &st);
+               if (error == 0)
+                       error = copyout(&st, uap->ub, sizeof(*uap->ub));
+               nlookup_done(&nd);
+       }
        return (error);
 }
 
index bb3a19f..7070c85 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.7 2004/09/28 00:25:29 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.8 2004/09/30 18:59:48 dillon Exp $
  */
 
 #include <sys/param.h>
                VDESC_NO_OFFSET,                                        \
                VDESC_NO_OFFSET)
 
+#define VNODEOP_DESC_INIT_NCP_CRED(name)                               \
+       VNODEOP_DESC_INIT(name, 0, NULL,                                \
+               VDESC_NO_OFFSET,                                        \
+               __offsetof(VARGSSTRUCT(name), a_cred),                  \
+               VDESC_NO_OFFSET,                                        \
+               VDESC_NO_OFFSET)
+
 #define VNODEOP_DESC_INIT_DVP_VPP_CNP(name)                            \
        static int VOFFNAME(name)[] = {                                 \
                __offsetof(VARGSSTRUCT(name), a_dvp),                   \
 
 VNODEOP_DESC_INIT_SIMPLE(default);
 VNODEOP_DESC_INIT_VP(islocked);
-VNODEOP_DESC_INIT_NCP(resolve);
+VNODEOP_DESC_INIT_NCP_CRED(resolve);
 VNODEOP_DESC_INIT_DVP_VPP_CNP(lookup);
 VNODEOP_DESC_INIT_DVP_VPP_CNP(cachedlookup);
 VNODEOP_DESC_INIT_DVP_VPP_CNP(create);
@@ -193,6 +200,7 @@ VNODEOP_DESC_INIT_VP(revoke);
 VNODEOP_DESC_INIT_VP_CRED(mmap);
 VNODEOP_DESC_INIT_VP(fsync);
 VNODEOP_DESC_INIT_DVP_VP_CNP(remove);
+VNODEOP_DESC_INIT_NCP_CRED(nremove);
 VNODEOP_DESC_INIT_TDVP_VP_CNP(link);
 
 static int VOFFNAME(rename)[] = { 
@@ -284,7 +292,7 @@ vop_islocked(struct vop_ops *ops, struct vnode *vp, struct thread *td)
 }
 
 int
-vop_resolve(struct vop_ops *ops, struct namecache *ncp)
+vop_resolve(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred)
 {
        struct vop_resolve_args ap;
        int error;
@@ -292,6 +300,7 @@ vop_resolve(struct vop_ops *ops, struct namecache *ncp)
        ap.a_head.a_desc = &vop_resolve_desc;
        ap.a_head.a_ops = ops;
        ap.a_ncp = ncp;
+       ap.a_cred = cred;
 
        DO_OPS(ops, error, &ap, vop_resolve);
        return(error);
@@ -649,6 +658,21 @@ vop_remove(struct vop_ops *ops, struct vnode *dvp, struct namecache *par,
        return(error);
 }
 
+int
+vop_nremove(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred)
+{
+       struct vop_nremove_args ap;
+       int error;
+
+       ap.a_head.a_desc = &vop_nremove_desc;
+       ap.a_head.a_ops = ops;
+       ap.a_ncp = ncp;
+       ap.a_cred = cred;
+
+       DO_OPS(ops, error, &ap, vop_nremove);
+       return(error);
+}
+
 int
 vop_link(struct vop_ops *ops, struct vnode *tdvp, struct namecache *par,
        struct vnode *vp, struct componentname *cnp)
@@ -1428,6 +1452,15 @@ vop_remove_ap(struct vop_remove_args *ap)
        return(error);
 }
 
+int
+vop_nremove_ap(struct vop_nremove_args *ap)
+{
+       int error;
+
+       DO_OPS(ap->a_head.a_ops, error, ap, vop_nremove);
+       return(error);
+}
+
 int
 vop_link_ap(struct vop_link_args *ap)
 {
index a73e644..d2f98e1 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)file.h      8.3 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/sys/file.h,v 1.22.2.7 2002/11/21 23:39:24 sam Exp $
- * $DragonFly: src/sys/sys/file.h,v 1.10 2004/05/13 23:49:25 dillon Exp $
+ * $DragonFly: src/sys/sys/file.h,v 1.11 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_FILE_H_
@@ -56,6 +56,7 @@ struct file;
 struct ucred;
 struct vnode;
 struct lwkt_port;
+struct namecache;
 
 struct fileops {
        struct lwkt_port *fo_port;
@@ -108,6 +109,7 @@ struct file {
        caddr_t f_data;         /* vnode or socket */
        int     f_count;        /* reference count */
        int     f_msgcount;     /* reference count from message queue */
+       struct namecache *f_ncp; /* ncp (required for directories) */
 };
 
 LIST_HEAD(filelist, file);
index 9e1de6a..fa50d9e 100644 (file)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/kern_syscall.h,v 1.18 2004/06/05 16:34:07 dillon Exp $
+ * $DragonFly: src/sys/sys/kern_syscall.h,v 1.19 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_KERN_SYSCALL_H_
@@ -36,7 +36,9 @@ union fcntl_dat;
 struct image_args;
 struct mbuf;
 struct msghdr;
+struct namecache;
 struct nameidata;
+struct nlookupdata;
 struct rlimit;
 struct rusage;
 struct sigaction;
@@ -117,10 +119,10 @@ int kern_socketpair(int domain, int type, int protocol, int *sockv);
  * Prototypes for syscalls in kern/vfs_syscalls.c
  */
 int kern_access(struct nameidata *nd, int aflags);
-int kern_chdir(struct nameidata *nd);
+int kern_chdir(struct nlookupdata *nd);
 int kern_chmod(struct nameidata *nd, int mode);
 int kern_chown(struct nameidata *nd, int uid, int gid);
-int kern_chroot(struct vnode *vp);
+/*int kern_chroot(struct namecache *ncp);*/
 int kern_fstatfs(int fd, struct statfs *buf);
 int kern_ftruncate(int fd, off_t length);
 int kern_futimes(int fd, struct timeval *tptr);
@@ -134,7 +136,7 @@ int kern_open(struct nameidata *nd, int flags, int mode, int *res);
 int kern_readlink(struct nameidata *nd, char *buf, int count, int *res);
 int kern_rename(struct nameidata *fromnd, struct nameidata *tond);
 int kern_rmdir(struct nameidata *nd);
-int kern_stat(struct nameidata *nd, struct stat *st);
+int kern_stat(struct nlookupdata *nd, struct stat *st);
 int kern_statfs(struct nameidata *nd, struct statfs *buf);
 int kern_symlink(char *path, struct nameidata *nd);
 int kern_truncate(struct nameidata *nd, off_t length);
index ffb206b..878b3d0 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.12 2004/08/17 18:57:32 dillon Exp $
+ * $DragonFly: src/sys/sys/mount.h,v 1.13 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_MOUNT_H_
@@ -145,6 +145,7 @@ struct mount {
        struct vop_ops  *mnt_vn_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 */
 };
 #endif /* _KERNEL || _KERNEL_STRUCTURES */
 
@@ -339,13 +340,14 @@ TAILQ_HEAD(mntlist, mount);       /* struct mntlist */
  * Operations supported on mounted file system.
  */
 #ifdef __STDC__
+struct nlookupdata;
 struct nameidata;
 struct mbuf;
 #endif
 
 struct vfsops {
        int     (*vfs_mount)    (struct mount *mp, char *path, caddr_t data,
-                                   struct nameidata *ndp, struct thread *td);
+                                   struct thread *td);
        int     (*vfs_start)    (struct mount *mp, int flags,
                                    struct thread *td);
        int     (*vfs_unmount)  (struct mount *mp, int mntflags,
@@ -371,8 +373,8 @@ struct vfsops {
                                        struct thread *td);
 };
 
-#define VFS_MOUNT(MP, PATH, DATA, NDP, P) \
-       (*(MP)->mnt_op->vfs_mount)(MP, PATH, DATA, NDP, P)
+#define VFS_MOUNT(MP, PATH, DATA, P) \
+       (*(MP)->mnt_op->vfs_mount)(MP, PATH, DATA, P)
 #define VFS_START(MP, FLAGS, P)          (*(MP)->mnt_op->vfs_start)(MP, FLAGS, P)
 #define VFS_UNMOUNT(MP, FORCE, P) (*(MP)->mnt_op->vfs_unmount)(MP, FORCE, P)
 #define VFS_ROOT(MP, VPP)        (*(MP)->mnt_op->vfs_root)(MP, VPP)
index b9bf1ad..15d0b85 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.9 2004/09/28 00:25:31 dillon Exp $
+ * $DragonFly: src/sys/sys/namecache.h,v 1.10 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_NAMECACHE_H_
@@ -144,23 +144,25 @@ void      cache_lock(struct namecache *ncp);
 void   cache_unlock(struct namecache *ncp);
 void   cache_setvp(struct namecache *ncp, struct vnode *vp);
 void   cache_setunresolved(struct namecache *ncp);
-void   cache_get(struct namecache *ncp);
-void   cache_put(struct namecache *ncp);
 int    cache_lookup(struct vnode *dvp, struct vnode **vpp,
                        struct componentname *cnp);
-void   cache_mount(struct vnode *dvp, struct vnode *tvp);
-void   cache_enter(struct vnode *dvp, struct namecache *par,
-                       struct vnode *vp, struct componentname *cnp);
+void   cache_enter(struct vnode *dvp, struct vnode *vp,
+                       struct componentname *cnp);
 struct namecache *cache_nlookup(struct namecache *par, struct nlcomponent *nlc);
-struct namecache *vfs_cache_setroot(struct vnode *vp);
-struct namecache *cache_vptoncp(struct vnode *vp);
-int    cache_resolve(struct namecache *ncp);
+struct namecache *cache_allocroot(struct vnode *vp);
+void   vfs_cache_setroot(struct vnode *vp, struct namecache *ncp);
+
+int    cache_resolve(struct namecache *ncp, struct ucred *cred);
 void   cache_purge(struct vnode *vp);
 void   cache_purgevfs (struct mount *mp);
-void   cache_drop(struct namecache *ncp);
+struct namecache *cache_get(struct namecache *ncp);
 struct namecache *cache_hold(struct namecache *ncp);
+void   cache_put(struct namecache *ncp);
+void   cache_drop(struct namecache *ncp);
 int    cache_leaf_test (struct vnode *vp);
 int    vfs_cache_lookup(struct vop_lookup_args *ap);
+int    cache_vget(struct namecache *, struct ucred *, int, struct vnode **);
+int    cache_vref(struct namecache *, struct ucred *, struct vnode **);
 
 #endif
 
index b57c1b8..4e87372 100644 (file)
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/nlookup.h,v 1.1 2004/09/28 00:25:31 dillon Exp $
+ * $DragonFly: src/sys/sys/nlookup.h,v 1.2 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_NLOOKUP_H_
 #define        _SYS_NLOOKUP_H_
 
+struct vattr;
+struct mount;
+struct namecache;
+struct thread;
+struct ucred;
+
 /*
  * nlookup component
  */
@@ -46,7 +52,12 @@ struct nlcomponent {
 };
 
 /*
- * Encapsulation of nlookup parameters
+ * Encapsulation of nlookup parameters.
+ *
+ * Note on nl_flags and nl_op: nl_flags supports a simplified subset of 
+ * namei's original CNP flags.  nl_op (e.g. NAMEI_*) does no in any way
+ * effect the state of the returned namecache and is only used to enforce
+ * access checks.
  */
 struct nlookupdata {
        struct namecache *nl_ncp;       /* start-point and result */
@@ -61,12 +72,12 @@ struct nlookupdata {
        int             nl_loopcnt;     /* symlinks encountered */
 };
 
-#define NLC_FOLLOW             CNP_FOLLOW
-#define NLC_NOCROSSMOUNT       CNP_NOCROSSMOUNT
-#define NLC_HASBUF             CNP_HASBUF
-#define NLC_ISWHITEOUT         CNP_ISWHITEOUT
-#define NLC_WILLBEDIR          CNP_WILLBEDIR
-#define NLC_NCPISLOCKED                CNP_LOCKLEAF
+#define NLC_FOLLOW             0x00000001      /* follow leaf symlink */
+#define NLC_NOCROSSMOUNT       0x00000002      /* do not cross mount points */
+#define NLC_HASBUF             0x00000004      /* nl_path is allocated */
+#define NLC_ISWHITEOUT         0x00000008
+#define NLC_WILLBEDIR          0x00000010
+#define NLC_NCPISLOCKED                0x00000020
 
 #ifdef _KERNEL
 
@@ -74,10 +85,12 @@ int nlookup_init(struct nlookupdata *, const char *, enum uio_seg, int);
 void nlookup_done(struct nlookupdata *);
 struct namecache *nlookup_simple(const char *str, enum uio_seg seg, 
                                int niflags, int *error);
+int nlookup_mp(struct mount *mp, struct namecache **ncpp);
 int nlookup(struct nlookupdata *);
 int nreadsymlink(struct nlookupdata *nd, struct namecache *ncp, 
                                struct nlcomponent *nlc);
-
+int naccess(struct namecache *ncp, int vmode, struct ucred *cred);
+int naccess_va(struct vattr *va, int vmode, struct ucred *cred);
 
 #endif
 
index 6a18c32..53fc719 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)systm.h     8.7 (Berkeley) 3/29/95
  * $FreeBSD: src/sys/sys/systm.h,v 1.111.2.18 2002/12/17 18:04:02 sam Exp $
- * $DragonFly: src/sys/sys/systm.h,v 1.22 2004/09/30 10:18:07 joerg Exp $
+ * $DragonFly: src/sys/sys/systm.h,v 1.23 2004/09/30 18:59:50 dillon Exp $
  */
 
 #ifndef _SYS_SYSTM_H_
@@ -76,7 +76,6 @@ extern long dumplo;           /* offset into dumpdev */
 extern dev_t rootdev;          /* root device */
 extern dev_t rootdevs[2];      /* possible root devices */
 extern char *rootdevnames[2];  /* names of possible root devices */
-extern struct vnode *rootvp;   /* vnode equivalent to above */
 
 extern int boothowto;          /* reboot flags, from console subsystem */
 extern int bootverbose;                /* nonzero to print verbose messages */
index 6c8e6d3..62243dd 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.6 2004/09/28 00:25:31 dillon Exp $
+ * $DragonFly: src/sys/sys/vfsops.h,v 1.7 2004/09/30 18:59:50 dillon Exp $
  */
 
 /*
@@ -96,7 +96,7 @@ struct vop_islocked_args {
 struct vop_resolve_args {
        struct vop_generic_args a_head;
        struct namecache *a_ncp;
-       struct componentname *a_cnp;
+       struct ucred *a_cred;
 };
 
 struct vop_lookup_args {
@@ -254,6 +254,12 @@ struct vop_remove_args {
        struct componentname *a_cnp;
 };
 
+struct vop_nremove_args {
+       struct vop_generic_args a_head;
+       struct namecache *a_ncp;                /* locked namespace */
+       struct ucred *a_cred;
+};
+
 struct vop_link_args {
        struct vop_generic_args a_head;
        struct vnode *a_tdvp;
@@ -578,7 +584,8 @@ struct vop_ops {
        int     (*vop_destroyvobject)(struct vop_destroyvobject_args *);
        int     (*vop_getvobject)(struct vop_getvobject_args *);
        int     (*vop_vfsset)(struct vop_vfsset_args *);
-#define vop_ops_last_field     vop_vfsset
+       int     (*vop_nremove)(struct vop_nremove_args *);
+#define vop_ops_last_field     vop_nremove
 };
 
 #define VVF_JOURNAL_HOOK       0x0001          /* FUTURE */
@@ -628,6 +635,7 @@ union vop_args_union {
        struct vop_mmap_args vu_mmap;
        struct vop_fsync_args vu_fsync;
        struct vop_remove_args vu_remove;
+       struct vop_nremove_args vu_nremove;
        struct vop_link_args vu_link;
        struct vop_rename_args vu_rename;
        struct vop_mkdir_args vu_mkdir;
@@ -672,7 +680,7 @@ union vop_args_union {
  * in a message and dispatch it to the correct thread.
  */
 int vop_islocked(struct vop_ops *ops, struct vnode *vp, struct thread *td);
-int vop_resolve(struct vop_ops *ops, struct namecache *ncp);
+int vop_resolve(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred);
 int vop_lookup(struct vop_ops *ops, struct vnode *dvp, 
                struct vnode **vpp, struct componentname *cnp);
 int vop_cachedlookup(struct vop_ops *ops, struct vnode *dvp, 
@@ -776,6 +784,8 @@ int vop_getvobject(struct vop_ops *ops,
                struct vnode *vp, struct vm_object **objpp);
 int vop_vfsset(struct vop_ops *ops, int op, const char *opstr);
 
+int vop_nremove(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred);
+
 /*
  * Kernel VOP forwarding wrappers.  These are called when a VFS such as
  * nullfs or unionfs needs to push down into another VFS, changing the 
@@ -808,6 +818,7 @@ int vop_revoke_ap(struct vop_revoke_args *ap);
 int vop_mmap_ap(struct vop_mmap_args *ap);
 int vop_fsync_ap(struct vop_fsync_args *ap);
 int vop_remove_ap(struct vop_remove_args *ap);
+int vop_nremove_ap(struct vop_nremove_args *ap);
 int vop_link_ap(struct vop_link_args *ap);
 int vop_rename_ap(struct vop_rename_args *ap);
 int vop_mkdir_ap(struct vop_mkdir_args *ap);
@@ -868,6 +879,7 @@ extern struct vnodeop_desc vop_revoke_desc;
 extern struct vnodeop_desc vop_mmap_desc;
 extern struct vnodeop_desc vop_fsync_desc;
 extern struct vnodeop_desc vop_remove_desc;
+extern struct vnodeop_desc vop_nremove_desc;
 extern struct vnodeop_desc vop_link_desc;
 extern struct vnodeop_desc vop_rename_desc;
 extern struct vnodeop_desc vop_mkdir_desc;
index af22985..d14ff62 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.22 2004/09/04 23:12:53 dillon Exp $
+ * $DragonFly: src/sys/sys/vnode.h,v 1.23 2004/09/30 18:59:51 dillon Exp $
  */
 
 #ifndef _SYS_VNODE_H_
@@ -192,8 +192,15 @@ struct vnode {
 #define        IO_SEQSHIFT     16              /* seq heuristic in upper 16 bits */
 
 /*
- *  Modes.  Some values same as Ixxx entries from inode.h for now.
+ * Modes.  Note that these V-modes must match file S_I*USR, SUID, SGID,
+ * and SVTX flag bits.
+ *
+ * VCREATE, VDELETE, and VEXCL may only be used in naccess() calls.
  */
+#define VDELETE        040000          /* delete if the file/dir exists */
+#define VCREATE        020000          /* create if the file/dir does not exist */
+#define VEXCL  010000          /* error if the file/dir already exists */
+
 #define        VSUID   04000           /* set user id on execution */
 #define        VSGID   02000           /* set group id on execution */
 #define        VSVTX   01000           /* save swapped text even after use */
@@ -253,6 +260,7 @@ extern      int             vttoif_tab[];
  * Global vnode data.
  */
 extern struct vnode *rootvnode;        /* root (i.e. "/") vnode */
+extern  struct namecache *rootncp;     /* root (i.e. "/") namecache */
 extern int desiredvnodes;              /* number of vnodes desired */
 extern time_t syncdelay;               /* max time to delay syncing data */
 extern time_t filedelay;               /* time to delay syncing files */
index f104f28..d180679 100644 (file)
@@ -28,7 +28,7 @@
  * 
  *     @(#) src/sys/cfs/coda_vfsops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
  * $FreeBSD: src/sys/coda/coda_vfsops.c,v 1.24.2.1 2001/07/26 20:36:45 iedowse Exp $
- * $DragonFly: src/sys/vfs/coda/Attic/coda_vfsops.c,v 1.15 2004/05/26 19:11:08 dillon Exp $
+ * $DragonFly: src/sys/vfs/coda/Attic/coda_vfsops.c,v 1.16 2004/09/30 18:59:53 dillon Exp $
  * 
  */
 
@@ -113,7 +113,6 @@ coda_mount(struct mount *vfsp,      /* Allocated and initialized by mount(2) */
           char *path,          /* path covered: ignored by the fs-layer */
           caddr_t data,        /* Need to define a data type for this in
                                 * netbsd? */
-          struct nameidata *ndp, /* Clobber this to lookup the device name */
           struct thread *td)   /* The ever-famous proc pointer */
 {
     struct vnode *dvp;
@@ -124,6 +123,7 @@ coda_mount(struct mount *vfsp,      /* Allocated and initialized by mount(2) */
     ViceFid rootfid;
     ViceFid ctlfid;
     int error;
+    struct nameidata nd;
 
     ENTRY;
 
@@ -137,9 +137,9 @@ coda_mount(struct mount *vfsp,      /* Allocated and initialized by mount(2) */
     }
     
     /* Validate mount device.  Similar to getmdev(). */
-    NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, data, td);
-    error = namei(ndp);
-    dvp = ndp->ni_vp;
+    NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, data, td);
+    error = namei(&nd);
+    dvp = nd.ni_vp;
 
     if (error) {
        MARK_INT_FAIL(CODA_MOUNT_STATS);
@@ -148,12 +148,12 @@ coda_mount(struct mount *vfsp,    /* Allocated and initialized by mount(2) */
     if (dvp->v_type != VCHR) {
        MARK_INT_FAIL(CODA_MOUNT_STATS);
        vrele(dvp);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
+       NDFREE(&nd, NDF_ONLY_PNBUF);
        return(ENXIO);
     }
     udev = dvp->v_udev;
     vrele(dvp);
-    NDFREE(ndp, NDF_ONLY_PNBUF);
+    NDFREE(&nd, NDF_ONLY_PNBUF);
 
 #if 0  /* YYY huh? what paranoia is this? */
     /*
index 466baae..e60782d 100644 (file)
@@ -28,7 +28,7 @@
  * 
  *     @(#) src/sys/cfs/coda_vfsops.h,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ 
  * $FreeBSD: src/sys/coda/coda_vfsops.h,v 1.4 1999/08/28 00:40:57 peter Exp $
- * $DragonFly: src/sys/vfs/coda/Attic/coda_vfsops.h,v 1.4 2003/06/26 05:55:07 dillon Exp $
+ * $DragonFly: src/sys/vfs/coda/Attic/coda_vfsops.h,v 1.5 2004/09/30 18:59:53 dillon Exp $
  * 
  */
 
@@ -47,8 +47,7 @@ struct cfid {
 struct mount;
 
 int coda_vfsopstats_init(void);
-int coda_mount(struct mount *, char *, caddr_t, struct nameidata *, 
-                      struct thread *);
+int coda_mount(struct mount *, char *, caddr_t, struct thread *);
 int coda_start(struct mount *, int, struct thread *);
 int coda_unmount(struct mount *, int, struct thread *);
 int coda_root(struct mount *, struct vnode **);
index 3738350..0082cf6 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.8 2004/08/17 18:57:33 dillon Exp $
+ * $DragonFly: src/sys/vfs/fdesc/fdesc_vfsops.c,v 1.9 2004/09/30 18:59:54 dillon Exp $
  */
 
 /*
@@ -62,7 +62,7 @@ extern struct vnodeopv_entry_desc fdesc_vnodeop_entries[];
 static MALLOC_DEFINE(M_FDESCMNT, "FDESC mount", "FDESC mount structure");
 
 static int     fdesc_mount (struct mount *mp, char *path, caddr_t data,
-                                struct nameidata *ndp, struct thread *td);
+                                struct thread *td);
 static int     fdesc_unmount (struct mount *mp, int mntflags,
                                   struct thread *td);
 static int     fdesc_statfs (struct mount *mp, struct statfs *sbp,
@@ -72,8 +72,7 @@ static int    fdesc_statfs (struct mount *mp, struct statfs *sbp,
  * Mount the per-process file descriptors (/dev/fd)
  */
 static int
-fdesc_mount(struct mount *mp, char *path, caddr_t data,
-       struct nameidata *ndp, struct thread *td)
+fdesc_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        int error = 0;
        struct fdescmount *fmp;
index fc1d6f2..70582ef 100644 (file)
@@ -5,7 +5,7 @@
  *  University of Utah, Department of Computer Science
  *
  * $FreeBSD: src/sys/gnu/ext2fs/ext2_lookup.c,v 1.21.2.3 2002/11/17 02:02:42 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_lookup.c,v 1.13 2004/04/24 04:32:03 drhodus Exp $
+ * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_lookup.c,v 1.14 2004/09/30 18:59:56 dillon Exp $
  */
 /*
  * Copyright (c) 1989, 1993
@@ -542,7 +542,7 @@ searchloop:
         * Insert name into cache (as non-existent) if appropriate.
         */
        if ((cnp->cn_flags & CNP_MAKEENTRY) && nameiop != NAMEI_CREATE)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (ENOENT);
 
 found:
@@ -689,7 +689,7 @@ found:
         * Insert name into cache if appropriate.
         */
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (0);
 }
 
index a61432f..e996702 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.19 2004/08/28 19:02:12 dillon Exp $
+ *     $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.20 2004/09/30 18:59:56 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -76,8 +76,7 @@ extern struct vnodeopv_entry_desc ext2_fifoop_entries[];
 
 static int ext2_fhtovp (struct mount *, struct fid *, struct vnode **);
 static int ext2_flushfiles (struct mount *mp, int flags, struct thread *td);
-static int ext2_mount (struct mount *,
-           char *, caddr_t, struct nameidata *, struct thread *);
+static int ext2_mount (struct mount *, char *, caddr_t, struct thread *);
 static int ext2_mountfs (struct vnode *, struct mount *, struct thread *);
 static int ext2_reload (struct mount *mountp, struct ucred *cred,
                        struct thread *p);
@@ -135,6 +134,7 @@ ext2_mountroot(void)
        struct ext2_sb_info *fs;
        struct mount *mp;
        struct thread *td = curthread;
+       struct vnode *rootvp;
        struct ufsmount *ump;
        u_int size;
        int error;
@@ -185,7 +185,7 @@ ext2_mountroot(void)
 static int
 ext2_mount(struct mount *mp, char *path,
           caddr_t data,        /* this is actually a (struct ufs_args *) */
-          struct nameidata *ndp, struct thread *td)
+          struct thread *td)
 {
        struct vnode *devvp;
        struct ufs_args args;
@@ -195,6 +195,7 @@ ext2_mount(struct mount *mp, char *path,
        int error, flags;
        mode_t accessmode;
        struct ucred *cred;
+       struct nameidata nd;
 
        if ((error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) != 0)
                return (error);
@@ -223,7 +224,7 @@ ext2_mount(struct mount *mp, char *path,
                        fs->s_rd_only = 1;
                }
                if (!error && (mp->mnt_flag & MNT_RELOAD))
-                       error = ext2_reload(mp, ndp->ni_cnd.cn_cred, td);
+                       error = ext2_reload(mp, proc0.p_ucred, td);
                if (error)
                        return (error);
                devvp = ump->um_devvp;
@@ -273,11 +274,11 @@ ext2_mount(struct mount *mp, char *path,
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       if ((error = namei(ndp)) != 0)
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       if ((error = namei(&nd)) != 0)
                return (error);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       devvp = ndp->ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
 
        if (!vn_isdisk(devvp, &error)) {
                vrele(devvp);
@@ -657,7 +658,7 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td)
         */
        if ((error = vfs_mountedon(devvp)) != 0)
                return (error);
-       if (count_udev(devvp->v_udev) > 0 && devvp != rootvp)
+       if (count_udev(devvp->v_udev) > 0)
                return (EBUSY);
        if ((error = vinvalbuf(devvp, V_SAVE, td, 0, 0)) != 0)
                return (error);
index 5b83bfb..17f30b8 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.20 2004/08/28 19:02:14 dillon Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.21 2004/09/30 18:59:57 dillon Exp $
  */
 
 
@@ -87,8 +87,7 @@ static int    hpfs_sync (struct mount *, int, struct ucred *,
 
 #if defined(__DragonFly__)
 struct sockaddr;
-static int     hpfs_mount (struct mount *, char *, caddr_t,
-                               struct nameidata *, struct thread *);
+static int     hpfs_mount (struct mount *, char *, caddr_t, struct thread *);
 static int     hpfs_init (struct vfsconf *);
 static int     hpfs_checkexp (struct mount *, struct sockaddr *,
                                   int *, struct ucred **);
@@ -167,13 +166,14 @@ hpfs_mount(struct mount *mp,
 #else /* defined(__NetBSD__) */
           const char *path, void *data,
 #endif
-          struct nameidata *ndp, struct thread *td)
+          struct thread *td)
 {
        u_int           size;
        int             err = 0;
        struct vnode    *devvp;
        struct hpfs_args args;
        struct hpfsmount *hpmp = 0;
+       struct nameidata nd;
 
        dprintf(("hpfs_mount():\n"));
        /*
@@ -216,14 +216,15 @@ hpfs_mount(struct mount *mp,
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       err = namei(ndp);
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       err = namei(&nd);
        if (err) {
                /* can't get devvp!*/
                goto error_1;
        }
 
-       devvp = ndp->ni_vp;
+       devvp = nd.ni_vp;
+       /* XXX NDFREE */
 
 #if defined(__DragonFly__)
        if (!vn_isdisk(devvp, &err)) 
@@ -321,7 +322,7 @@ hpfs_mountfs(struct vnode *devvp, struct mount *mp, struct hpfs_args *argsp,
        if (devvp->v_object)
                ncount -= 1;
 #endif
-       if (ncount > 0 && devvp != rootvp)
+       if (ncount > 0)
                return (EBUSY);
 
 #if defined(__DragonFly__)
index 80e61c6..f814332 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $
- * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.17 2004/08/28 19:02:14 dillon Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.18 2004/09/30 18:59:57 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -1223,7 +1223,7 @@ hpfs_lookup(struct vop_lookup_args *ap)
                if ((flags & CNP_MAKEENTRY) &&
                    (!(flags & CNP_ISLASTCN) || 
                     (nameiop != NAMEI_DELETE && nameiop != NAMEI_CREATE)))
-                       cache_enter(dvp, NCPNULL, *ap->a_vpp, cnp);
+                       cache_enter(dvp, *ap->a_vpp, cnp);
        }
        return (error);
 }
index 81d1ea3..e2da6f0 100644 (file)
@@ -39,7 +39,7 @@
  *
  *     @(#)cd9660_lookup.c     8.2 (Berkeley) 1/23/94
  * $FreeBSD: src/sys/isofs/cd9660/cd9660_lookup.c,v 1.23.2.2 2001/11/04 06:19:47 dillon Exp $
- * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.12 2004/04/24 04:32:04 drhodus Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_lookup.c,v 1.13 2004/09/30 18:59:59 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -309,7 +309,7 @@ notfound:
         * Insert name into cache (as non-existent) if appropriate.
         */
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        if (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME)
                return (EROFS);
        return (ENOENT);
@@ -389,7 +389,7 @@ found:
         * Insert name into cache if appropriate.
         */
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (0);
 }
 
index e5eeb19..f36b311 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.20 2004/08/28 19:02:15 dillon Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.21 2004/09/30 18:59:59 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -69,8 +69,7 @@ extern struct vnodeopv_entry_desc cd9660_fifoop_entries[];
 MALLOC_DEFINE(M_ISOFSMNT, "ISOFS mount", "ISOFS mount structure");
 MALLOC_DEFINE(M_ISOFSNODE, "ISOFS node", "ISOFS vnode private part");
 
-static int cd9660_mount (struct mount *,
-           char *, caddr_t, struct nameidata *, struct thread *);
+static int cd9660_mount (struct mount *, char *, caddr_t, struct thread *);
 static int cd9660_unmount (struct mount *, int, struct thread *);
 static int cd9660_root (struct mount *, struct vnode **);
 static int cd9660_statfs (struct mount *, struct statfs *, struct thread *);
@@ -146,6 +145,7 @@ static int
 iso_mountroot(struct mount *mp, struct thread *td)
 {
        struct iso_args args;
+       struct vnode *rootvp;
        int error;
 
        if ((error = bdevvp(rootdev, &rootvp))) {
@@ -180,8 +180,7 @@ iso_mountroot(struct mount *mp, struct thread *td)
  * mount system call
  */
 static int
-cd9660_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-            struct thread *td)
+cd9660_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct vnode *devvp;
        struct iso_args args;
@@ -189,6 +188,7 @@ cd9660_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        int error;
        mode_t accessmode;
        struct iso_mnt *imp = 0;
+       struct nameidata nd;
 
        if ((mp->mnt_flag & MNT_ROOTFS) != 0) {
                return (iso_mountroot(mp, td));
@@ -214,11 +214,11 @@ cd9660_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       if ((error = namei(ndp)))
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       if ((error = namei(&nd)))
                return (error);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       devvp = ndp->ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
 
        if (!vn_isdisk(devvp, &error)) {
                vrele(devvp);
@@ -292,12 +292,11 @@ iso_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td,
        /*
         * Disallow multiple mounts of the same device.
         * Disallow mounting of a device that is currently in use
-        * (except for root, which might share swap device for miniroot).
         * Flush out any old buffers remaining from a previous use.
         */
        if ((error = vfs_mountedon(devvp)))
                return error;
-       if (count_udev(devvp->v_udev) > 0 && devvp != rootvp)
+       if (count_udev(devvp->v_udev) > 0)
                return EBUSY;
        if ((error = vinvalbuf(devvp, V_SAVE, td, 0, 0)))
                return (error);
index abc1e07..50f46df 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.17 2004/08/28 19:02:17 dillon Exp $
+ * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.18 2004/09/30 19:00:01 dillon Exp $
  */
 
 
@@ -69,8 +69,7 @@ MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part");
 extern struct vop_ops *mfs_vnode_vops;
 
 static int     mfs_mount (struct mount *mp,
-                       char *path, caddr_t data, struct nameidata *ndp, 
-                       struct thread *td);
+                       char *path, caddr_t data, struct thread *td);
 static int     mfs_start (struct mount *mp, int flags, struct thread *td);
 static int     mfs_statfs (struct mount *mp, struct statfs *sbp, 
                        struct thread *td);
@@ -211,8 +210,7 @@ mfsstrategy(struct buf *bp)
  */
 /* ARGSUSED */
 static int
-mfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-         struct thread *td)
+mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct vnode *devvp;
        struct mfs_args args;
index beb2248..12791b8 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/msdosfs/msdosfs_lookup.c,v 1.30.2.1 2000/11/03 15:55:39 bp Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_lookup.c,v 1.10 2004/04/24 04:32:04 drhodus Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_lookup.c,v 1.11 2004/09/30 19:00:04 dillon Exp $ */
 /*     $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $   */
 
 /*-
@@ -373,7 +373,7 @@ notfound:
         * Insert name into cache (as non-existent) if appropriate.
         */
        if ((cnp->cn_flags & CNP_MAKEENTRY) && nameiop != NAMEI_CREATE)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (ENOENT);
 
 found:
@@ -549,7 +549,7 @@ foundroot:
         * Insert name into cache if appropriate.
         */
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (0);
 }
 
index 4cf0629..c5340cd 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.18 2004/08/17 18:57:34 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.19 2004/09/30 19:00:04 dillon Exp $ */
 /*     $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $   */
 
 /*-
@@ -96,7 +96,7 @@ static int    msdosfs_fhtovp (struct mount *, struct fid *,
 static int     msdosfs_checkexp (struct mount *, struct sockaddr *, 
                                    int *, struct ucred **);
 static int     msdosfs_mount (struct mount *, char *, caddr_t,
-                                  struct nameidata *, struct thread *);
+                                  struct thread *);
 static int     msdosfs_root (struct mount *, struct vnode **);
 static int     msdosfs_statfs (struct mount *, struct statfs *,
                                    struct thread *);
@@ -164,6 +164,7 @@ msdosfs_mountroot(void)
        size_t size;
        int error;
        struct msdosfs_args args;
+       struct vnode *rootvp;
 
        if (root_device->dv_class != DV_DISK)
                return (ENODEV);
@@ -224,8 +225,7 @@ msdosfs_mountroot(void)
  * special file to treat as a filesystem.
  */
 static int
-msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-             struct thread *td)
+msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct vnode *devvp;      /* vnode for blk device to mount */
        struct msdosfs_args args; /* will hold data from mount request */
@@ -235,6 +235,7 @@ msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        int error, flags;
        mode_t accessmode;
        struct proc *p = td->td_proc;
+       struct nameidata nd;
 
        KKASSERT(p);
 
@@ -298,12 +299,12 @@ msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       error = namei(ndp);
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       error = namei(&nd);
        if (error)
                return (error);
-       devvp = ndp->ni_vp;
-       NDFREE(ndp, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
 
        if (!vn_isdisk(devvp, &error)) {
                vrele(devvp);
@@ -381,13 +382,12 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp, struct thread *td,
        /*
         * Disallow multiple mounts of the same device.
         * Disallow mounting of a device that is currently in use
-        * (except for root, which might share swap device for miniroot).
         * Flush out any old buffers remaining from a previous use.
         */
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       if (count_udev(devvp->v_udev) > 0 && devvp != rootvp)
+       if (count_udev(devvp->v_udev) > 0)
                return (EBUSY);
        vn_lock(devvp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
        error = vinvalbuf(devvp, V_SAVE, td, 0, 0);
index 5c74161..9d0d420 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.20 2004/08/17 18:57:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vfsops.c,v 1.21 2004/09/30 19:00:08 dillon Exp $
  */
 
 #include "opt_bootp.h"
@@ -115,7 +115,7 @@ static void nfs_decode_args (struct nfsmount *nmp,
 static int     mountnfs (struct nfs_args *,struct mount *,
                        struct sockaddr *,char *,char *,struct vnode **);
 static int     nfs_mount ( struct mount *mp, char *path, caddr_t data,
-                       struct nameidata *ndp, struct thread *td);
+                       struct thread *td);
 static int     nfs_unmount ( struct mount *mp, int mntflags,
                        struct thread *td);
 static int     nfs_root ( struct mount *mp, struct vnode **vpp);
@@ -574,7 +574,6 @@ nfs_mountroot(mp)
 
        mp->mnt_flag |= MNT_ROOTFS;
        mp->mnt_vnodecovered = NULLVP;
-       rootvp = vp;
        vfs_unbusy(mp, td);
 
        /*
@@ -783,8 +782,7 @@ nfs_decode_args(nmp, argp)
  */
 /* ARGSUSED */
 static int
-nfs_mount(struct mount *mp, char *path, caddr_t data,
-       struct nameidata *ndp, struct thread *td)
+nfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        int error;
        struct nfs_args args;
index 28ac6a1..8a37be9 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.30 2004/09/26 01:24:56 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.31 2004/09/30 19:00:08 dillon Exp $
  */
 
 
@@ -952,7 +952,7 @@ nfs_lookup(struct vop_lookup_args *ap)
                                cnp->cn_flags |= CNP_CACHETIMEOUT;
                                cnp->cn_timeout = toval;
                        }
-                       cache_enter(dvp, NCPNULL, NULL, cnp);
+                       cache_enter(dvp, NULL, cnp);
                }
                nfsm_postop_attr(dvp, attrflag);
                m_freem(mrep);
@@ -1032,7 +1032,7 @@ nfs_lookup(struct vop_lookup_args *ap)
        if ((cnp->cn_flags & CNP_MAKEENTRY) &&
            (cnp->cn_nameiop != NAMEI_DELETE || !(flags & CNP_ISLASTCN))) {
                np->n_ctime = np->n_vattr.va_ctime.tv_sec;
-               cache_enter(dvp, NCPNULL, newvp, cnp);
+               cache_enter(dvp, newvp, cnp);
        }
        *vpp = newvp;
        m_freem(mrep);
@@ -1384,7 +1384,7 @@ nfsmout:
                        vput(newvp);
        } else {
                if (cnp->cn_flags & CNP_MAKEENTRY)
-                       cache_enter(dvp, NCPNULL, newvp, cnp);
+                       cache_enter(dvp, newvp, cnp);
                *vpp = newvp;
        }
        VTONFS(dvp)->n_flag |= NMODIFIED;
@@ -1516,7 +1516,7 @@ nfsmout:
        }
        if (!error) {
                if (cnp->cn_flags & CNP_MAKEENTRY)
-                       cache_enter(dvp, NCPNULL, newvp, cnp);
+                       cache_enter(dvp, newvp, cnp);
                /*
                 * The new np may have enough info for access
                 * checks, make sure rucred and wucred are
@@ -2449,7 +2449,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop)
                                dp->d_type =
                                    IFTODT(VTTOIF(np->n_vattr.va_type));
                                ndp->ni_vp = newvp;
-                               cache_enter(ndp->ni_dvp, NCPNULL, ndp->ni_vp, cnp);
+                               cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp);
                            }
                        } else {
                            /* Just skip over the file handle */
index fef91b9..0a09f58 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.21 2004/08/28 19:02:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.22 2004/09/30 19:00:11 dillon Exp $
  */
 
 
@@ -99,8 +99,7 @@ static int    ntfs_sync (struct mount *, int, struct ucred *,
 
 #if defined(__DragonFly__)
 struct sockaddr;
-static int     ntfs_mount (struct mount *, char *, caddr_t,
-                               struct nameidata *, struct thread *);
+static int     ntfs_mount (struct mount *, char *, caddr_t, struct thread *);
 static int     ntfs_init (struct vfsconf *);
 static int     ntfs_checkexp (struct mount *, struct sockaddr *,
                                   int *, struct ucred **);
@@ -156,7 +155,7 @@ static int
 ntfs_mountroot(void)
 {
        struct mount *mp;
-       extern struct vnode *rootvp;
+       struct vnode *rootvp;
        struct thread *td = curthread;  /* XXX */
        struct ntfs_args args;
        lwkt_tokref ilock;
@@ -223,12 +222,14 @@ ntfs_mount(struct mount *mp,
 #else
           const char *path, void *data,
 #endif
-          struct nameidata *ndp, struct thread *td)
+          struct thread *td)
 {
        size_t          size;
        int             err = 0;
        struct vnode    *devvp;
        struct ntfs_args args;
+       struct nameidata nd;
+       struct vnode *rootvp;
 
 #ifdef __DragonFly__
        /*
@@ -299,14 +300,14 @@ ntfs_mount(struct mount *mp,
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       err = namei(ndp);
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       err = namei(&nd);
        if (err) {
                /* can't get devvp!*/
                goto error_1;
        }
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       devvp = ndp->ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
 
 #if defined(__DragonFly__)
        if (!vn_isdisk(devvp, &err)) 
@@ -434,7 +435,7 @@ ntfs_mountfs(struct vnode *devvp, struct mount *mp, struct ntfs_args *argsp,
        if (devvp->v_object)
                ncount -= 1;
 #endif
-       if (ncount > 1 && devvp != rootvp)
+       if (ncount > 1)
                return (EBUSY);
 #if defined(__DragonFly__)
        VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, td);
index fa67c8d..0bfd87d 100644 (file)
@@ -36,7 +36,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $
- * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.15 2004/09/26 01:24:57 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.16 2004/09/30 19:00:11 dillon Exp $
  *
  */
 
@@ -797,7 +797,7 @@ ntfs_lookup(struct vop_lookup_args *ap)
        }
 
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(dvp, NCPNULL, *ap->a_vpp, cnp);
+               cache_enter(dvp, *ap->a_vpp, cnp);
 
        return (error);
 }
index d2fa168..dd3e541 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.11 2004/08/17 18:57:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.12 2004/09/30 19:00:13 dillon Exp $
  */
 
 /*
@@ -64,7 +64,7 @@ static int    nullfs_fhtovp(struct mount *mp, struct fid *fidp,
 static int     nullfs_checkexp(struct mount *mp, struct sockaddr *nam,
                                    int *extflagsp, struct ucred **credanonp);
 static int     nullfs_mount(struct mount *mp, char *path, caddr_t data,
-                                 struct nameidata *ndp, struct thread *td);
+                                 struct thread *td);
 static int     nullfs_quotactl(struct mount *mp, int cmd, uid_t uid,
                                     caddr_t arg, struct thread *td);
 static int     nullfs_root(struct mount *mp, struct vnode **vpp);
@@ -82,8 +82,7 @@ static int    nullfs_extattrctl(struct mount *mp, int cmd,
  * Mount null layer
  */
 static int
-nullfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-            struct thread *td)
+nullfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        int error = 0;
        struct null_args args;
@@ -92,6 +91,7 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        struct null_mount *xmp;
        u_int size;
        int isvnunlocked = 0;
+       struct nameidata nd;
 
        NULLFSDEBUG("nullfs_mount(mp = %p)\n", (void *)mp);
 
@@ -100,7 +100,6 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
         */
        if (mp->mnt_flag & MNT_UPDATE) {
                return (EOPNOTSUPP);
-               /* return VFS_MOUNT(MOUNTTONULLMOUNT(mp)->nullm_vfs, path, data, ndp, p);*/
        }
 
        /*
@@ -122,9 +121,9 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        /*
         * Find lower node
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT | CNP_LOCKLEAF,
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT | CNP_LOCKLEAF,
                UIO_USERSPACE, args.target, td);
-       error = namei(ndp);
+       error = namei(&nd);
        /*
         * Re-lock vnode.
         */
@@ -133,15 +132,15 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
 
        if (error)
                return (error);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
+       NDFREE(&nd, NDF_ONLY_PNBUF);
 
        /*
         * Sanity check on lower vnode
         */
-       lowerrootvp = ndp->ni_vp;
+       lowerrootvp = nd.ni_vp;
 
-       vrele(ndp->ni_dvp);
-       ndp->ni_dvp = NULLVP;
+       vrele(nd.ni_dvp);
+       nd.ni_dvp = NULLVP;
 
        /*
         * Check multi null mount to avoid `lock against myself' panic.
index c38c9df..4c4ba90 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_io.c,v 1.6.2.1 2000/10/25 02:11:10 bp Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_io.c,v 1.10 2004/04/22 17:56:44 cpressey Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_io.c,v 1.11 2004/09/30 19:00:15 dillon Exp $
  *
  */
 #include <sys/param.h>
@@ -137,7 +137,7 @@ nwfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
                                VTONW(newvp)->n_ctime = VTONW(newvp)->n_vattr.va_ctime.tv_sec;
                                cn.cn_nameptr = dp.d_name;
                                cn.cn_namelen = dp.d_namlen;
-                               cache_enter(vp, NCPNULL, newvp, &cn);
+                               cache_enter(vp, newvp, &cn);
                                vput(newvp);
                        } else
                                error = 0;
index 3ba33ab..2a50d5c 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.11 2004/08/17 18:57:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_vfsops.c,v 1.12 2004/09/30 19:00:15 dillon Exp $
  */
 #include "opt_ncp.h"
 #ifndef NCP
@@ -69,8 +69,7 @@ SYSCTL_NODE(_vfs, OID_AUTO, nwfs, CTLFLAG_RW, 0, "Netware file system");
 SYSCTL_INT(_vfs_nwfs, OID_AUTO, version, CTLFLAG_RD, &nwfs_version, 0, "");
 SYSCTL_INT(_vfs_nwfs, OID_AUTO, debuglevel, CTLFLAG_RW, &nwfs_debuglevel, 0, "");
 
-static int nwfs_mount(struct mount *, char *, caddr_t,
-                       struct nameidata *, struct thread *);
+static int nwfs_mount(struct mount *, char *, caddr_t, struct thread *);
 static int nwfs_quotactl(struct mount *, int, uid_t, caddr_t, struct thread *);
 static int nwfs_root(struct mount *, struct vnode **);
 static int nwfs_start(struct mount *, int, struct thread *);
@@ -143,8 +142,7 @@ nwfs_initnls(struct nwmount *nmp) {
  * data - addr in user space of mount params 
  */
 static int
-nwfs_mount(struct mount *mp, char *path, caddr_t data, 
-          struct nameidata *ndp, struct thread *td)
+nwfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct nwfs_args args;    /* will hold data from mount request */
        size_t size;
index 6190c4e..5ed12a6 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_vnops.c,v 1.6.2.3 2001/03/14 11:26:59 bp Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.15 2004/09/26 01:24:59 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.16 2004/09/30 19:00:15 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -441,7 +441,7 @@ nwfs_create(struct vop_create_args *ap)
                        *vpp = vp;
                }
                if (cnp->cn_flags & CNP_MAKEENTRY)
-                       cache_enter(dvp, NCPNULL, vp, cnp);
+                       cache_enter(dvp, vp, cnp);
        }
        return (error);
 }
@@ -1029,7 +1029,7 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & CNP_ISD
        }
        if ((cnp->cn_flags & CNP_MAKEENTRY)/* && !islastcn*/) {
                VTONW(*vpp)->n_ctime = VTONW(*vpp)->n_vattr.va_ctime.tv_sec;
-               cache_enter(dvp, NCPNULL, *vpp, cnp);
+               cache_enter(dvp, *vpp, cnp);
        }
        return (0);
 }
index 1a802db..a724df1 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.11 2004/08/28 19:02:25 dillon Exp $
+ * $DragonFly: src/sys/vfs/portal/portal_vfsops.c,v 1.12 2004/09/30 19:00:17 dillon Exp $
  */
 
 /*
@@ -63,7 +63,7 @@ extern struct vnodeopv_entry_desc portal_vnodeop_entries[];
 static MALLOC_DEFINE(M_PORTALFSMNT, "PORTAL mount", "PORTAL mount structure");
 
 static int     portal_mount (struct mount *mp, char *path, caddr_t data,
-                                 struct nameidata *ndp, struct thread *td);
+                                 struct thread *td);
 static int     portal_unmount (struct mount *mp, int mntflags,
                                    struct thread *td);
 static int     portal_root (struct mount *mp, struct vnode **vpp);
@@ -74,8 +74,7 @@ static int    portal_statfs (struct mount *mp, struct statfs *sbp,
  * Mount the per-process file descriptors (/dev/fd)
  */
 static int
-portal_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-            struct thread *td)
+portal_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct file *fp;
        struct portal_args args;
index 689733d..a56b596 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.8 2004/08/28 19:02:27 dillon Exp $
+ * $DragonFly: src/sys/vfs/procfs/procfs_vfsops.c,v 1.9 2004/09/30 19:00:19 dillon Exp $
  */
 
 /*
@@ -55,7 +55,7 @@
 extern struct vnodeopv_entry_desc procfs_vnodeop_entries[];
 
 static int     procfs_mount (struct mount *mp, char *path, caddr_t data,
-                                 struct nameidata *ndp, struct thread *td);
+                                 struct thread *td);
 static int     procfs_statfs (struct mount *mp, struct statfs *sbp,
                                   struct thread *td);
 static int     procfs_unmount (struct mount *mp, int mntflags,
@@ -68,8 +68,7 @@ static int    procfs_unmount (struct mount *mp, int mntflags,
  */
 /* ARGSUSED */
 static int
-procfs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-            struct thread *td)
+procfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        size_t size;
        int error;
index 6a062ea..d3b8107 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_io.c,v 1.3.2.3 2003/01/17 08:20:26 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_io.c,v 1.11 2004/05/03 05:19:50 cpressey Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_io.c,v 1.12 2004/09/30 19:00:21 dillon Exp $
  *
  */
 #include <sys/param.h>
@@ -161,7 +161,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
                        if (!error) {
                                cn.cn_nameptr = de.d_name;
                                cn.cn_namelen = de.d_namlen;
-                               cache_enter(vp, NCPNULL, newvp, &cn);
+                               cache_enter(vp, newvp, &cn);
                                vput(newvp);
                        }
                }
index 4f76325..28c6a47 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.13 2004/08/17 18:57:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_vfsops.c,v 1.14 2004/09/30 19:00:21 dillon Exp $
  */
 #include "opt_netsmb.h"
 #ifndef NETSMB
@@ -81,8 +81,7 @@ SYSCTL_INT(_vfs_smbfs, OID_AUTO, debuglevel, CTLFLAG_RW, &smbfs_debuglevel, 0, "
 static MALLOC_DEFINE(M_SMBFSHASH, "SMBFS hash", "SMBFS hash table");
 
 
-static int smbfs_mount(struct mount *, char *, caddr_t,
-                       struct nameidata *, struct thread *);
+static int smbfs_mount(struct mount *, char *, caddr_t, struct thread *);
 static int smbfs_quotactl(struct mount *, int, uid_t, caddr_t, struct thread *);
 static int smbfs_root(struct mount *, struct vnode **);
 static int smbfs_start(struct mount *, int, struct thread *);
@@ -133,8 +132,7 @@ MODULE_DEPEND(smbfs, libmchain, 1, 1, 1);
 int smbfs_pbuf_freecnt = -1;   /* start out unlimited */
 
 static int
-smbfs_mount(struct mount *mp, char *path, caddr_t data, 
-           struct nameidata *ndp, struct thread *td)
+smbfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct smbfs_args args;           /* will hold data from mount request */
        struct smbmount *smp = NULL;
index bd48b3b..c72f097 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.2.2.8 2003/04/04 08:57:23 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.17 2004/09/26 01:25:00 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.18 2004/09/30 19:00:21 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -525,7 +525,7 @@ smbfs_create(struct vop_create_args *ap)
                return error;
        *vpp = vp;
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(dvp, NCPNULL, vp, cnp);
+               cache_enter(dvp, vp, cnp);
        return error;
 }
 
@@ -1265,7 +1265,7 @@ smbfs_lookup(struct vop_lookup_args *ap)
        }
        if ((cnp->cn_flags & CNP_MAKEENTRY)/* && !islastcn*/) {
 /*             VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/
-               cache_enter(dvp, NCPNULL, *vpp, cnp);
+               cache_enter(dvp, *vpp, cnp);
        }
        return 0;
 }
index 7e206e5..07552d2 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.7 2004/08/17 18:57:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.8 2004/09/30 19:00:23 dillon Exp $
  */
 
 /* udf_vfsops.c */
@@ -100,8 +100,7 @@ MALLOC_DEFINE(M_UDFNODE, "UDF node", "UDF node structure");
 MALLOC_DEFINE(M_UDFMOUNT, "UDF mount", "UDF mount structure");
 MALLOC_DEFINE(M_UDFFENTRY, "UDF fentry", "UDF file entry structure");
 
-static int udf_mount(struct mount *, char *, caddr_t, struct nameidata *,
-                    struct thread *);
+static int udf_mount(struct mount *, char *, caddr_t, struct thread *);
 static int udf_unmount(struct mount *, int, struct thread *);
 static int udf_root(struct mount *, struct vnode **);
 static int udf_statfs(struct mount *, struct statfs *, struct thread *);
@@ -133,14 +132,14 @@ MODULE_VERSION(udf, 1);
 static int udf_mountfs(struct vnode *, struct mount *, struct thread *);
 
 static int
-udf_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-         struct thread *td)
+udf_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct vnode *devvp;    /* vnode of the mount device */
        struct udf_args args;
        struct udf_mnt *imp = 0;
        size_t size;
        int error;
+       struct nameidata nd;
 
        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                return (EROFS);
@@ -162,11 +161,11 @@ udf_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        }
 
        /* Check that the mount device exists */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       if ((error = namei(ndp)))
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       if ((error = namei(&nd)))
                return(error);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       devvp = ndp->ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
 
        if (vn_isdisk(devvp, &error) == 0) {
                vrele(devvp);
index 9856bce..653c039 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.7 2004/08/28 19:02:29 dillon Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.8 2004/09/30 19:00:23 dillon Exp $
  */
 
 /* udf_vnops.c */
@@ -1004,7 +1004,7 @@ lookloop:
 
                        /* Put this entry in the cache */
                        if (flags & CNP_MAKEENTRY)
-                               cache_enter(dvp, NCPNULL, *vpp, a->a_cnp);
+                               cache_enter(dvp, *vpp, a->a_cnp);
                }
        } else {
                /* Name wasn't found on this pass.  Do another pass? */
@@ -1017,7 +1017,7 @@ lookloop:
 
                /* Enter name into cache as non-existant */
                if (flags & CNP_MAKEENTRY)
-                       cache_enter(dvp, NCPNULL, *vpp, a->a_cnp);
+                       cache_enter(dvp, *vpp, a->a_cnp);
 
                if ((flags & CNP_ISLASTCN) &&
                    (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME)) {
index 1b99a8f..c377e37 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.24 2004/08/28 19:02:30 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.25 2004/09/30 19:00:25 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -67,8 +67,7 @@ static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part");
 static int     ffs_sbupdate (struct ufsmount *, int);
 static int     ffs_reload (struct mount *,struct ucred *,struct thread *);
 static int     ffs_oldfscompat (struct fs *);
-static int     ffs_mount (struct mount *, char *, caddr_t,
-                               struct nameidata *, struct thread *);
+static int     ffs_mount (struct mount *, char *, caddr_t, struct thread *);
 static int     ffs_init (struct vfsconf *);
 
 static struct vfsops ufs_vfsops = {
@@ -136,7 +135,6 @@ static int
 ffs_mount(struct mount *mp,            /* mount struct pointer */
           char *path,                  /* path to mount point */
           caddr_t data,                        /* arguments to FS specific mount */
-          struct nameidata *ndp,       /* mount point credentials */
           struct thread        *td)            /* process requesting mount */
 {
        size_t          size;
@@ -149,6 +147,8 @@ ffs_mount(struct mount *mp,         /* mount struct pointer */
        int error, flags, ronly = 0;
        mode_t accessmode;
        struct ucred *cred;
+       struct nameidata nd;
+       struct vnode *rootvp;
 
        KKASSERT(td->td_proc);
        cred = td->td_proc->p_ucred;
@@ -218,7 +218,7 @@ ffs_mount(struct mount *mp,         /* mount struct pointer */
                        ronly = 1;
                }
                if (!err && (mp->mnt_flag & MNT_RELOAD))
-                       err = ffs_reload(mp, ndp->ni_cnd.cn_cred, td);
+                       err = ffs_reload(mp, NULL, td);
                if (err) {
                        goto error_1;
                }
@@ -287,15 +287,15 @@ ffs_mount(struct mount *mp,               /* mount struct pointer */
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
-       err = namei(ndp);
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
+       err = namei(&nd);
        if (err) {
                /* can't get devvp!*/
                goto error_1;
        }
 
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       devvp = ndp->ni_vp;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       devvp = nd.ni_vp;
 
        if (!vn_isdisk(devvp, &err))
                goto error_2;
@@ -633,13 +633,12 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td,
        /*
         * Disallow multiple mounts of the same device.
         * Disallow mounting of a device that is currently in use
-        * (except for root, which might share swap device for miniroot).
         * Flush out any old buffers remaining from a previous use.
         */
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       if (count_udev(devvp->v_udev) > 0 && devvp != rootvp)
+       if (count_udev(devvp->v_udev) > 0)
                return (EBUSY);
        vn_lock(devvp, NULL, LK_EXCLUSIVE | LK_RETRY, td);
        error = vinvalbuf(devvp, V_SAVE, td, 0, 0);
index cd65c47..630f29e 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_lookup.c        8.15 (Berkeley) 6/16/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_lookup.c,v 1.33.2.7 2001/09/22 19:22:13 iedowse Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_lookup.c,v 1.13 2004/07/18 19:43:48 drhodus Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_lookup.c,v 1.14 2004/09/30 19:00:25 dillon Exp $
  */
 
 #include "opt_ufs.h"
@@ -451,7 +451,7 @@ notfound:
         * Insert name into cache (as non-existent) if appropriate.
         */
        if ((cnp->cn_flags & CNP_MAKEENTRY) && nameiop != NAMEI_CREATE)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (ENOENT);
 
 found:
@@ -622,7 +622,7 @@ found:
         * Insert name into cache if appropriate.
         */
        if (cnp->cn_flags & CNP_MAKEENTRY)
-               cache_enter(vdp, NCPNULL, *vpp, cnp);
+               cache_enter(vdp, *vpp, cnp);
        return (0);
 }
 
index d5106c6..6670f28 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.11 2004/08/17 18:57:36 dillon Exp $
+ * $DragonFly: src/sys/vfs/umapfs/Attic/umap_vfsops.c,v 1.12 2004/09/30 19:00:27 dillon Exp $
  */
 
 /*
@@ -64,7 +64,7 @@ static int    umapfs_fhtovp (struct mount *mp, struct fid *fidp,
 static int     umapfs_checkexp (struct mount *mp, struct sockaddr *nam,
                                    int *extflagsp, struct ucred **credanonp);
 static int     umapfs_mount (struct mount *mp, char *path, caddr_t data,
-                                 struct nameidata *ndp, struct thread *td);
+                                 struct thread *td);
 static int     umapfs_quotactl (struct mount *mp, int cmd, uid_t uid,
                                     caddr_t arg, struct thread *td);
 static int     umapfs_root (struct mount *mp, struct vnode **vpp);
@@ -86,13 +86,13 @@ static int  umapfs_extattrctl (struct mount *mp, int cmd,
  * Mount umap layer
  */
 static int
-umapfs_mount(struct mount *mp, char *path, caddr_t data,
-       struct nameidata *ndp, struct thread *td)
+umapfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        struct umap_args args;
        struct vnode *lowerrootvp, *vp;
        struct vnode *umapm_rootvp;
        struct umap_mount *amp;
+       struct nameidata nd;
        u_int size;
        int error;
 #ifdef DEBUG
@@ -114,7 +114,6 @@ umapfs_mount(struct mount *mp, char *path, caddr_t data,
         */
        if (mp->mnt_flag & MNT_UPDATE) {
                return (EOPNOTSUPP);
-               /* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, td));*/
        }
 
        /*
@@ -127,22 +126,22 @@ umapfs_mount(struct mount *mp, char *path, caddr_t data,
        /*
         * Find lower node
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT | CNP_LOCKLEAF,
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT | CNP_LOCKLEAF,
                UIO_USERSPACE, args.target, td);
-       error = namei(ndp);
+       error = namei(&nd);
        if (error)
                return (error);
-       NDFREE(ndp, NDF_ONLY_PNBUF);
+       NDFREE(&nd, NDF_ONLY_PNBUF);
 
        /*
         * Sanity check on lower vnode
         */
-       lowerrootvp = ndp->ni_vp;
+       lowerrootvp = nd.ni_vp;
 #ifdef DEBUG
        printf("vp = %p, check for VDIR...\n", (void *)lowerrootvp);
 #endif
-       vrele(ndp->ni_dvp);
-       ndp->ni_dvp = 0;
+       vrele(nd.ni_dvp);
+       nd.ni_dvp = 0;
 
        if (lowerrootvp->v_type != VDIR) {
                vput(lowerrootvp);
index 8d54a19..faa3f4d 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.14 2004/08/17 18:57:36 dillon Exp $
+ * $DragonFly: src/sys/vfs/union/union_vfsops.c,v 1.15 2004/09/30 19:00:29 dillon Exp $
  */
 
 /*
@@ -61,7 +61,7 @@ static MALLOC_DEFINE(M_UNIONFSMNT, "UNION mount", "UNION mount structure");
 
 extern int     union_init (struct vfsconf *);
 static int     union_mount (struct mount *mp, char *path, caddr_t data,
-                                struct nameidata *ndp, struct thread *td);
+                                struct thread *td);
 static int     union_root (struct mount *mp, struct vnode **vpp);
 static int     union_statfs (struct mount *mp, struct statfs *sbp,
                                  struct thread *td);
@@ -72,8 +72,7 @@ static int    union_unmount (struct mount *mp, int mntflags,
  * Mount union filesystem
  */
 static int
-union_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
-           struct thread *td)
+union_mount(struct mount *mp, char *path, caddr_t data, struct thread *td)
 {
        int error = 0;
        struct union_args args;
@@ -81,6 +80,7 @@ union_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        struct vnode *upperrootvp = NULLVP;
        struct union_mount *um = 0;
        struct ucred *cred = 0;
+       struct nameidata nd;
        char *cp = 0;
        int len;
        u_int size;
@@ -134,10 +134,10 @@ union_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
         * Obtain upper vnode by calling namei() on the path.  The
         * upperrootvp will be turned referenced but not locked.
         */
-       NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT,
+       NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_WANTPARENT,
                UIO_USERSPACE, args.target, td);
 
-       error = namei(ndp);
+       error = namei(&nd);
 
 #if 0
        if (lowerrootvp->v_tag == VT_UNION)
@@ -146,10 +146,10 @@ union_mount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
        if (error)
                goto bad;
 
-       NDFREE(ndp, NDF_ONLY_PNBUF);
-       upperrootvp = ndp->ni_vp;
-       vrele(ndp->ni_dvp);
-       ndp->ni_dvp = NULL;
+       NDFREE(&nd, NDF_ONLY_PNBUF);
+       upperrootvp = nd.ni_vp;
+       vrele(nd.ni_dvp);
+       nd.ni_dvp = NULL;
 
        UDEBUG(("mount_root UPPERVP %p locked = %d\n", upperrootvp,
            VOP_ISLOCKED(upperrootvp, NULL)));