From 28623bf96348e242220bd887d979bcc6543aa7f3 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 27 Oct 2006 04:56:34 +0000 Subject: [PATCH] Major namecache work primarily to support NULLFS. * Move the nc_mount field out of the namecache{} record and use a new namecache handle structure called nchandle { mount, ncp } for all API accesses to the namecache. * Remove all mount point linkages from the namecache topology. Each mount now has its own namecache topology rooted at the root of the mount point. Mount points are flagged in their underlying filesystem's namecache topology but instead of linking the mount into the topology, the flag simply triggers a mountlist scan to locate the mount. ".." is handled the same way... when the root of a topology is encountered the scan can traverse to the underlying filesystem via a field stored in the mount structure. * Ref the mount structure based on the number of nchandle structures referencing it, and do not kfree() the mount structure during a forced unmount if refs remain. These changes have the following effects: * Traversal across mount points no longer require locking of any sort, preventing process blockages occuring in one mount from leaking across a mount point to another mount. * Aliased namespaces such as occurs with NULLFS no longer duplicate the namecache topology of the underlying filesystem. Instead, a NULLFS mount simply shares the underlying topology (differentiating between it and the underlying topology by the fact that the name cache handles { mount, ncp } contain NULLFS's mount pointer. This saves an immense amount of memory and allows NULLFS to be used heavily within a system without creating any adverse impact on kernel memory or performance. * Since the namecache topology for a NULLFS mount is shared with the underyling mount, the namecache records are in fact the same records and thus full coherency between the NULLFS mount and the underlying filesystem is maintained by design. * Future efforts, such as a unionfs or shadow fs implementation, now have a mount structure to work with. The new API is a lot more flexible then the old one. --- sys/emulation/linux/linux_misc.c | 4 +- sys/emulation/linux/linux_stats.c | 6 +- sys/emulation/linux/linux_util.c | 6 +- sys/kern/imgact_elf.c | 4 +- sys/kern/init_main.c | 14 +- sys/kern/kern_acl.c | 10 +- sys/kern/kern_descrip.c | 26 +- sys/kern/kern_exec.c | 10 +- sys/kern/kern_jail.c | 10 +- sys/kern/kern_shutdown.c | 11 +- sys/kern/uipc_usrreq.c | 8 +- sys/kern/vfs_cache.c | 710 +++++++++++++++++---------- sys/kern/vfs_conf.c | 4 +- sys/kern/vfs_default.c | 128 ++--- sys/kern/vfs_jops.c | 54 +- sys/kern/vfs_journal.c | 16 +- sys/kern/vfs_nlookup.c | 258 +++++----- sys/kern/vfs_syscalls.c | 604 ++++++++++++----------- sys/kern/vfs_vnops.c | 60 ++- sys/kern/vfs_vopops.c | 60 +-- sys/sys/file.h | 7 +- sys/sys/filedesc.h | 12 +- sys/sys/jail.h | 9 +- sys/sys/kern_syscall.h | 5 +- sys/sys/mount.h | 10 +- sys/sys/namecache.h | 72 +-- sys/sys/nlookup.h | 26 +- sys/sys/vfsops.h | 88 ++-- sys/sys/vnode.h | 8 +- sys/vfs/gnu/ext2fs/ext2_vfsops.c | 4 +- sys/vfs/hpfs/hpfs_vfsops.c | 4 +- sys/vfs/isofs/cd9660/cd9660_rrip.c | 4 +- sys/vfs/isofs/cd9660/cd9660_vfsops.c | 4 +- sys/vfs/msdosfs/msdosfs_vfsops.c | 4 +- sys/vfs/nfs/nfs_serv.c | 72 +-- sys/vfs/nfs/nfs_subs.c | 30 +- sys/vfs/nfs/nfs_syscalls.c | 4 +- sys/vfs/nfs/nfs_vnops.c | 30 +- sys/vfs/ntfs/ntfs_vfsops.c | 4 +- sys/vfs/nullfs/null_vfsops.c | 46 +- sys/vfs/nullfs/null_vnops.c | 24 +- sys/vfs/udf/udf_vfsops.c | 4 +- sys/vfs/ufs/ffs_vfsops.c | 4 +- sys/vfs/union/union_vfsops.c | 4 +- sys/vm/vm_swap.c | 4 +- usr.bin/fstat/fstat.c | 29 +- 46 files changed, 1368 insertions(+), 1147 deletions(-) diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index 6282b6e25c..b59187628e 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.85.2.9 2002/09/24 08:11:41 mdodd Exp $ - * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.30 2006/09/11 20:24:59 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.31 2006/10/27 04:56:28 dillon Exp $ */ #include "opt_compat.h" @@ -265,7 +265,7 @@ sys_linux_uselib(struct linux_uselib_args *args) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) goto cleanup; /* diff --git a/sys/emulation/linux/linux_stats.c b/sys/emulation/linux/linux_stats.c index 6d0f9d6e03..a6407a3c7c 100644 --- a/sys/emulation/linux/linux_stats.c +++ b/sys/emulation/linux/linux_stats.c @@ -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.23 2006/09/10 01:26:38 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/linux_stats.c,v 1.24 2006/10/27 04:56:28 dillon Exp $ */ #include @@ -249,8 +249,8 @@ sys_linux_statfs(struct linux_statfs_args *args) if (error == 0) error = kern_statfs(&nd, &statfs); if (error == 0) { - if (nd.nl_ncp->nc_vp != NULL) - error = vn_get_namelen(nd.nl_ncp->nc_vp, &namelen); + if (nd.nl_nch.ncp->nc_vp != NULL) + error = vn_get_namelen(nd.nl_nch.ncp->nc_vp, &namelen); else error = EINVAL; } diff --git a/sys/emulation/linux/linux_util.c b/sys/emulation/linux/linux_util.c index 7e2d59c2b3..42a376aca5 100644 --- a/sys/emulation/linux/linux_util.c +++ b/sys/emulation/linux/linux_util.c @@ -28,7 +28,7 @@ * * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp * $FreeBSD: src/sys/compat/linux/linux_util.c,v 1.12.2.2 2001/11/05 19:08:23 marcel Exp $ - * $DragonFly: src/sys/emulation/linux/linux_util.c,v 1.13 2006/09/05 00:55:45 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/linux_util.c,v 1.14 2006/10/27 04:56:28 dillon Exp $ */ #include @@ -107,7 +107,7 @@ linux_copyin_path(char *uname, char **kname, int flags) error = nlookup(&nd); vp = NULL; if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error) goto dont_translate; @@ -131,7 +131,7 @@ linux_copyin_path(char *uname, char **kname, int flags) error = nlookup(&ndroot); vproot = NULL; if (error == 0) { - error = cache_vref(ndroot.nl_ncp, ndroot.nl_cred, + error = cache_vref(&ndroot.nl_nch, ndroot.nl_cred, &vproot); } nlookup_done(&ndroot); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 05d70b4a19..5b8dcaa2df 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/kern/imgact_elf.c,v 1.73.2.13 2002/12/28 19:49:41 dillon Exp $ - * $DragonFly: src/sys/kern/imgact_elf.c,v 1.42 2006/09/11 20:25:01 dillon Exp $ + * $DragonFly: src/sys/kern/imgact_elf.c,v 1.43 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -433,7 +433,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) if (error == 0) error = nlookup(nd); if (error == 0) - error = cache_vget(nd->nl_ncp, nd->nl_cred, LK_EXCLUSIVE, &imgp->vp); + error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, &imgp->vp); nlookup_done(nd); if (error) goto fail; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index fe9dbc74d4..580c0fab39 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -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.64 2006/09/19 11:47:35 corecode Exp $ + * $DragonFly: src/sys/kern/init_main.c,v 1.65 2006/10/27 04:56:31 dillon Exp $ */ #include "opt_init_path.h" @@ -452,18 +452,18 @@ start_init(void *dummy) mp = mountlist_boot_getfirst(); if (VFS_ROOT(mp, &vp)) panic("cannot find root vnode"); - if (mp->mnt_ncp == NULL) { - mp->mnt_ncp = cache_allocroot(mp, vp); - cache_unlock(mp->mnt_ncp); /* leave ref intact */ + if (mp->mnt_ncmountpt.ncp == NULL) { + cache_allocroot(&mp->mnt_ncmountpt, mp, vp); + cache_unlock(&mp->mnt_ncmountpt); /* leave ref intact */ } p->p_fd->fd_cdir = vp; vref(p->p_fd->fd_cdir); p->p_fd->fd_rdir = vp; vref(p->p_fd->fd_rdir); - vfs_cache_setroot(vp, cache_hold(mp->mnt_ncp)); + vfs_cache_setroot(vp, cache_hold(&mp->mnt_ncmountpt)); vn_unlock(vp); /* leave ref intact */ - p->p_fd->fd_ncdir = cache_hold(mp->mnt_ncp); - p->p_fd->fd_nrdir = cache_hold(mp->mnt_ncp); + cache_copy(&mp->mnt_ncmountpt, &p->p_fd->fd_ncdir); + cache_copy(&mp->mnt_ncmountpt, &p->p_fd->fd_nrdir); /* * Need just enough stack to hold the faked-up "execve()" arguments. diff --git a/sys/kern/kern_acl.c b/sys/kern/kern_acl.c index e2843e0d35..f239f31248 100644 --- a/sys/kern/kern_acl.c +++ b/sys/kern/kern_acl.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_acl.c,v 1.2.2.1 2000/07/28 18:48:16 rwatson Exp $ - * $DragonFly: src/sys/kern/kern_acl.c,v 1.15 2006/08/12 00:26:20 dillon Exp $ + * $DragonFly: src/sys/kern/kern_acl.c,v 1.16 2006/10/27 04:56:31 dillon Exp $ */ /* @@ -163,7 +163,7 @@ sys___acl_get_file(struct __acl_get_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error == 0) { error = vacl_get_acl(vp, uap->type, uap->aclp); @@ -187,7 +187,7 @@ sys___acl_set_file(struct __acl_set_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error == 0) { error = vacl_set_acl(vp, uap->type, uap->aclp); @@ -247,7 +247,7 @@ sys___acl_delete_file(struct __acl_delete_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error == 0) { @@ -290,7 +290,7 @@ sys___acl_aclcheck_file(struct __acl_aclcheck_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error == 0) { diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 2ff08f1234..5fd0f91c78 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -70,7 +70,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.74 2006/09/19 11:47:35 corecode Exp $ + * $DragonFly: src/sys/kern/kern_descrip.c,v 1.75 2006/10/27 04:56:31 dillon Exp $ */ #include "opt_compat.h" @@ -1413,10 +1413,8 @@ ffree(struct file *fp) nfiles--; spin_unlock_wr(&filehead_spin); crfree(fp->f_cred); - if (fp->f_ncp) { - cache_drop(fp->f_ncp); - fp->f_ncp = NULL; - } + if (fp->f_nchandle.ncp) + cache_drop(&fp->f_nchandle); kfree(fp, M_FILE); } @@ -1452,7 +1450,7 @@ fdinit(struct proc *p) if (fdp->fd_cdir) { newfdp->fd_cdir = fdp->fd_cdir; vref(newfdp->fd_cdir); - newfdp->fd_ncdir = cache_hold(fdp->fd_ncdir); + cache_copy(&fdp->fd_ncdir, &newfdp->fd_ncdir); } /* @@ -1462,12 +1460,12 @@ fdinit(struct proc *p) if (fdp->fd_rdir) { newfdp->fd_rdir = fdp->fd_rdir; vref(newfdp->fd_rdir); - newfdp->fd_nrdir = cache_hold(fdp->fd_nrdir); + cache_copy(&fdp->fd_nrdir, &newfdp->fd_nrdir); } if (fdp->fd_jdir) { newfdp->fd_jdir = fdp->fd_jdir; vref(newfdp->fd_jdir); - newfdp->fd_njdir = cache_hold(fdp->fd_njdir); + cache_copy(&fdp->fd_njdir, &newfdp->fd_njdir); } spin_unlock_rd(&fdp->fd_spin); @@ -1569,7 +1567,7 @@ again: */ if ((newfdp->fd_cdir = fdp->fd_cdir) != NULL) { vref(newfdp->fd_cdir); - newfdp->fd_ncdir = cache_hold(fdp->fd_ncdir); + cache_copy(&fdp->fd_ncdir, &newfdp->fd_ncdir); } /* * We must check for fd_rdir here, at least for now because @@ -1578,11 +1576,11 @@ again: */ if ((newfdp->fd_rdir = fdp->fd_rdir) != NULL) { vref(newfdp->fd_rdir); - newfdp->fd_nrdir = cache_hold(fdp->fd_nrdir); + cache_copy(&fdp->fd_nrdir, &newfdp->fd_nrdir); } if ((newfdp->fd_jdir = fdp->fd_jdir) != NULL) { vref(newfdp->fd_jdir); - newfdp->fd_njdir = cache_hold(fdp->fd_njdir); + cache_copy(&fdp->fd_njdir, &newfdp->fd_njdir); } newfdp->fd_refcnt = 1; newfdp->fd_nfiles = i; @@ -1738,15 +1736,15 @@ fdfree(struct proc *p) if (fdp->fd_files != fdp->fd_builtin_files) kfree(fdp->fd_files, M_FILEDESC); if (fdp->fd_cdir) { - cache_drop(fdp->fd_ncdir); + cache_drop(&fdp->fd_ncdir); vrele(fdp->fd_cdir); } if (fdp->fd_rdir) { - cache_drop(fdp->fd_nrdir); + cache_drop(&fdp->fd_nrdir); vrele(fdp->fd_rdir); } if (fdp->fd_jdir) { - cache_drop(fdp->fd_njdir); + cache_drop(&fdp->fd_njdir); vrele(fdp->fd_jdir); } if (fdp->fd_knlist) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 55d3020cfc..9033eb9975 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_exec.c,v 1.107.2.15 2002/07/30 15:40:46 nectar Exp $ - * $DragonFly: src/sys/kern/kern_exec.c,v 1.47 2006/10/20 17:02:16 dillon Exp $ + * $DragonFly: src/sys/kern/kern_exec.c,v 1.48 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -195,10 +195,10 @@ interpret: */ if ((error = nlookup(nd)) != 0) goto exec_fail; - error = cache_vget(nd->nl_ncp, nd->nl_cred, LK_EXCLUSIVE, &imgp->vp); + error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, &imgp->vp); KKASSERT(nd->nl_flags & NLC_NCPISLOCKED); nd->nl_flags &= ~NLC_NCPISLOCKED; - cache_unlock(nd->nl_ncp); + cache_unlock(&nd->nl_nch); if (error) goto exec_fail; @@ -344,8 +344,8 @@ interpret: execsigs(p); /* name this process - nameiexec(p, ndp) */ - len = min(nd->nl_ncp->nc_nlen, MAXCOMLEN); - bcopy(nd->nl_ncp->nc_name, p->p_comm, len); + len = min(nd->nl_nch.ncp->nc_nlen, MAXCOMLEN); + bcopy(nd->nl_nch.ncp->nc_name, p->p_comm, len); p->p_comm[len] = 0; bcopy(p->p_comm, p->p_lwp.lwp_thread->td_comm, MAXCOMLEN+1); diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 1575901f42..fdd83e420b 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -7,7 +7,7 @@ * ---------------------------------------------------------------------------- * * $FreeBSD: src/sys/kern/kern_jail.c,v 1.6.2.3 2001/08/17 01:00:26 rwatson Exp $ - * $DragonFly: src/sys/kern/kern_jail.c,v 1.12 2006/09/05 00:55:45 dillon Exp $ + * $DragonFly: src/sys/kern/kern_jail.c,v 1.13 2006/10/27 04:56:31 dillon Exp $ * */ @@ -73,7 +73,7 @@ kern_jail_attach(int jid) if (pr == NULL) return(EINVAL); - error = kern_chroot(pr->pr_root); + error = kern_chroot(&pr->pr_root); if (error) return(error); @@ -118,7 +118,7 @@ sys_jail(struct jail_args *uap) error = nlookup(&nd); if (error) goto nlookup_init_clean; - pr->pr_root = cache_hold(nd.nl_ncp); + cache_copy(&nd.nl_nch, &pr->pr_root); pr->pr_ip = j.ip_number; varsymset_init(&pr->pr_varsymset, NULL); @@ -295,7 +295,7 @@ retry: char *fullpath, *freepath; xp->pr_version = KINFO_PRISON_VERSION; xp->pr_id = pr->pr_id; - error = cache_fullpath(p, pr->pr_root, &fullpath, &freepath); + error = cache_fullpath(p, &pr->pr_root, &fullpath, &freepath); if (error == 0) { strlcpy(xp->pr_path, fullpath, sizeof(xp->pr_path)); kfree(freepath, M_TEMP); @@ -335,6 +335,6 @@ prison_free(struct prison *pr) if (pr->pr_linux != NULL) kfree(pr->pr_linux, M_PRISON); varsymset_clean(&pr->pr_varsymset); - cache_drop(pr->pr_root); + cache_drop(&pr->pr_root); kfree(pr, M_PRISON); } diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index db7ee4fbaa..681d5528be 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -37,7 +37,7 @@ * * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/kern_shutdown.c,v 1.72.2.12 2002/02/21 19:15:10 dillon Exp $ - * $DragonFly: src/sys/kern/kern_shutdown.c,v 1.39 2006/10/20 17:02:16 dillon Exp $ + * $DragonFly: src/sys/kern/kern_shutdown.c,v 1.40 2006/10/27 04:56:31 dillon Exp $ */ #include "opt_ddb.h" @@ -480,22 +480,19 @@ shutdown_cleanup_proc(struct proc *p) if ((fdp = p->p_fd) != NULL) { kern_closefrom(0); if (fdp->fd_cdir) { - cache_drop(fdp->fd_ncdir); + cache_drop(&fdp->fd_ncdir); vrele(fdp->fd_cdir); fdp->fd_cdir = NULL; - fdp->fd_ncdir = NULL; } if (fdp->fd_rdir) { - cache_drop(fdp->fd_nrdir); + cache_drop(&fdp->fd_nrdir); vrele(fdp->fd_rdir); fdp->fd_rdir = NULL; - fdp->fd_nrdir = NULL; } if (fdp->fd_jdir) { - cache_drop(fdp->fd_njdir); + cache_drop(&fdp->fd_njdir); vrele(fdp->fd_jdir); fdp->fd_jdir = NULL; - fdp->fd_njdir = NULL; } } if (p->p_vkernel) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index ff56ea9cd8..4744c5ef58 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -32,7 +32,7 @@ * * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94 * $FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.54.2.10 2003/03/04 17:28:09 nectar Exp $ - * $DragonFly: src/sys/kern/uipc_usrreq.c,v 1.29 2006/09/05 00:55:45 dillon Exp $ + * $DragonFly: src/sys/kern/uipc_usrreq.c,v 1.30 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -606,7 +606,7 @@ unp_bind(struct unpcb *unp, struct sockaddr *nam, struct thread *td) error = nlookup_init(&nd, buf, UIO_SYSSPACE, NLC_LOCKVP|NLC_CREATE); if (error == 0) error = nlookup(&nd); - if (error == 0 && nd.nl_ncp->nc_vp != NULL) + if (error == 0 && nd.nl_nch.ncp->nc_vp != NULL) error = EADDRINUSE; if (error) goto done; @@ -614,7 +614,7 @@ unp_bind(struct unpcb *unp, struct sockaddr *nam, struct thread *td) VATTR_NULL(&vattr); vattr.va_type = VSOCK; vattr.va_mode = (ACCESSPERMS & ~p->p_fd->fd_cmask); - error = VOP_NCREATE(nd.nl_ncp, &vp, nd.nl_cred, &vattr); + error = VOP_NCREATE(&nd.nl_nch, &vp, nd.nl_cred, &vattr); if (error == 0) { vp->v_socket = unp->unp_socket; unp->unp_vnode = vp; @@ -651,7 +651,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 7dd6df6aad..d83f12091d 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -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.78 2006/10/26 02:27:19 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_cache.c,v 1.79 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -149,8 +149,10 @@ SYSCTL_ULONG(_debug, OID_AUTO, numunres, CTLFLAG_RD, &numunres, 0, ""); SYSCTL_INT(_debug, OID_AUTO, vnsize, CTLFLAG_RD, 0, sizeof(struct vnode), ""); SYSCTL_INT(_debug, OID_AUTO, ncsize, CTLFLAG_RD, 0, sizeof(struct namecache), ""); -static int cache_resolve_mp(struct namecache *ncp); -static void cache_rehash(struct namecache *ncp); +static int cache_resolve_mp(struct mount *mp); +static void _cache_rehash(struct namecache *ncp); +static void _cache_lock(struct namecache *ncp); +static void _cache_setunresolved(struct namecache *ncp); /* * The new name cache statistics @@ -234,7 +236,7 @@ _cache_drop(struct namecache *ncp) TAILQ_EMPTY(&ncp->nc_list) ) { KKASSERT(ncp->nc_exlocks == 0); - cache_lock(ncp); + _cache_lock(ncp); cache_zap(ncp); } else { atomic_subtract_int(&ncp->nc_refs, 1); @@ -275,11 +277,11 @@ cache_unlink_parent(struct namecache *ncp) if ((par = ncp->nc_parent) != NULL) { ncp->nc_parent = NULL; - par = cache_hold(par); + par = _cache_hold(par); TAILQ_REMOVE(&par->nc_list, ncp, nc_entry); if (par->nc_vp && TAILQ_EMPTY(&par->nc_list)) vdrop(par->nc_vp); - cache_drop(par); + _cache_drop(par); } } @@ -307,12 +309,12 @@ cache_alloc(int nlen) */ ncp->nc_fsmid = cache_getnewfsmid(); TAILQ_INIT(&ncp->nc_list); - cache_lock(ncp); + _cache_lock(ncp); return(ncp); } static void -cache_free(struct namecache *ncp) +_cache_free(struct namecache *ncp) { KKASSERT(ncp->nc_refs == 1 && ncp->nc_exlocks == 1); if (ncp->nc_name) @@ -320,22 +322,50 @@ cache_free(struct namecache *ncp) kfree(ncp, M_VFSCACHE); } +void +cache_zero(struct nchandle *nch) +{ + nch->ncp = NULL; + nch->mount = NULL; +} + /* * Ref and deref a namecache structure. * * Warning: caller may hold an unrelated read spinlock, which means we can't * use read spinlocks here. */ -struct namecache * -cache_hold(struct namecache *ncp) +struct nchandle * +cache_hold(struct nchandle *nch) { - return(_cache_hold(ncp)); + _cache_hold(nch->ncp); + ++nch->mount->mnt_refs; + return(nch); } void -cache_drop(struct namecache *ncp) +cache_copy(struct nchandle *nch, struct nchandle *target) { - _cache_drop(ncp); + *target = *nch; + _cache_hold(target->ncp); + ++nch->mount->mnt_refs; +} + +void +cache_changemount(struct nchandle *nch, struct mount *mp) +{ + --nch->mount->mnt_refs; + nch->mount = mp; + ++nch->mount->mnt_refs; +} + +void +cache_drop(struct nchandle *nch) +{ + --nch->mount->mnt_refs; + _cache_drop(nch->ncp); + nch->ncp = NULL; + nch->mount = NULL; } /* @@ -359,8 +389,9 @@ cache_drop(struct namecache *ncp) * is handled). Or, alternatively, make an unconditional call to * cache_validate() or cache_resolve() after cache_lock() returns. */ +static void -cache_lock(struct namecache *ncp) +_cache_lock(struct namecache *ncp) { thread_t td; int didwarn; @@ -400,12 +431,8 @@ cache_lock(struct namecache *ncp) continue; didwarn = 1; printf("[diagnostic] cache_lock: blocked on %p", ncp); - if ((ncp->nc_flag & NCF_MOUNTPT) && ncp->nc_mount) - printf(" [MOUNTFROM %s]\n", ncp->nc_mount->mnt_stat.f_mntfromname); - else - printf(" \"%*.*s\"\n", - ncp->nc_nlen, ncp->nc_nlen, - ncp->nc_name); + printf(" \"%*.*s\"\n", + ncp->nc_nlen, ncp->nc_nlen, ncp->nc_name); } } @@ -415,8 +442,15 @@ cache_lock(struct namecache *ncp) } } +void +cache_lock(struct nchandle *nch) +{ + _cache_lock(nch->ncp); +} + +static int -cache_lock_nonblock(struct namecache *ncp) +_cache_lock_nonblock(struct namecache *ncp) { thread_t td; @@ -446,8 +480,15 @@ cache_lock_nonblock(struct namecache *ncp) } } +int +cache_lock_nonblock(struct nchandle *nch) +{ + return(_cache_lock_nonblock(nch->ncp)); +} + +static void -cache_unlock(struct namecache *ncp) +_cache_unlock(struct namecache *ncp) { thread_t td = curthread; @@ -465,6 +506,12 @@ cache_unlock(struct namecache *ncp) } } +void +cache_unlock(struct nchandle *nch) +{ + _cache_unlock(nch->ncp); +} + /* * ref-and-lock, unlock-and-deref functions. * @@ -473,45 +520,74 @@ cache_unlock(struct namecache *ncp) * initiated a recyclement. We want cache_get() to return a definitively * usable vnode or a definitively unresolved ncp. */ +static struct namecache * -cache_get(struct namecache *ncp) +_cache_get(struct namecache *ncp) { _cache_hold(ncp); - cache_lock(ncp); + _cache_lock(ncp); if (ncp->nc_vp && (ncp->nc_vp->v_flag & VRECLAIMED)) - cache_setunresolved(ncp); + _cache_setunresolved(ncp); return(ncp); } -int -cache_get_nonblock(struct namecache *ncp) +/* + * note: the same nchandle can be passed for both arguments. + */ +void +cache_get(struct nchandle *nch, struct nchandle *target) +{ + target->mount = nch->mount; + target->ncp = _cache_get(nch->ncp); + ++target->mount->mnt_refs; +} + +static int +_cache_get_nonblock(struct namecache *ncp) { /* XXX MP */ if (ncp->nc_exlocks == 0 || ncp->nc_locktd == curthread) { _cache_hold(ncp); - cache_lock(ncp); + _cache_lock(ncp); if (ncp->nc_vp && (ncp->nc_vp->v_flag & VRECLAIMED)) - cache_setunresolved(ncp); + _cache_setunresolved(ncp); return(0); } return(EWOULDBLOCK); } +int +cache_get_nonblock(struct nchandle *nch) +{ + return(_cache_get_nonblock(nch->ncp)); +} + +static __inline void -cache_put(struct namecache *ncp) +_cache_put(struct namecache *ncp) { - cache_unlock(ncp); + _cache_unlock(ncp); _cache_drop(ncp); } +void +cache_put(struct nchandle *nch) +{ + --nch->mount->mnt_refs; + _cache_put(nch->ncp); + nch->ncp = NULL; + nch->mount = NULL; +} + /* * Resolve an unresolved ncp by associating a vnode with it. If the * vnode is NULL, a negative cache entry is created. * * The ncp should be locked on entry and will remain locked on return. */ +static void -cache_setvp(struct namecache *ncp, struct vnode *vp) +_cache_setvp(struct namecache *ncp, struct vnode *vp) { KKASSERT(ncp->nc_flag & NCF_UNRESOLVED); ncp->nc_vp = vp; @@ -551,8 +627,16 @@ cache_setvp(struct namecache *ncp, struct vnode *vp) } void -cache_settimeout(struct namecache *ncp, int nticks) +cache_setvp(struct nchandle *nch, struct vnode *vp) { + _cache_setvp(nch->ncp, vp); +} + +void +cache_settimeout(struct nchandle *nch, int nticks) +{ + struct namecache *ncp = nch->ncp; + if ((ncp->nc_timeout = ticks + nticks) == 0) ncp->nc_timeout = 1; } @@ -574,8 +658,9 @@ cache_settimeout(struct namecache *ncp, int nticks) * NOTE: NCF_FSMID must be cleared so a refurbishment of the ncp, such as * in a create, properly propogates flag up the chain. */ +static void -cache_setunresolved(struct namecache *ncp) +_cache_setunresolved(struct namecache *ncp) { struct vnode *vp; @@ -610,31 +695,40 @@ cache_setunresolved(struct namecache *ncp) } } -/* - * Mark the namecache node as containing a mount point. - * - * XXX called with a ref'd but unlocked ncp. - */ void -cache_setmountpt(struct namecache *ncp, struct mount *mp) +cache_setunresolved(struct nchandle *nch) { - ncp->nc_mount = mp; - ncp->nc_flag |= NCF_MOUNTPT; - ncp->nc_parent->nc_flag |= NCF_MOUNTEDHERE; + _cache_setunresolved(nch->ncp); } /* - * Clean up a mount point in the namecache topology after an unmount. - * - * XXX we probably need to traverse the entire topology and clear - * the nc_mount pointer. + * Determine if we can clear NCF_ISMOUNTPT by scanning the mountlist + * looking for matches. This flag tells the lookup code when it must + * check for a mount linkage and also prevents the directories in question + * from being deleted or renamed. */ +static +int +cache_clrmountpt_callback(struct mount *mp, void *data) +{ + struct nchandle *nch = data; + + if (mp->mnt_ncmounton.ncp == nch->ncp) + return(1); + if (mp->mnt_ncmountpt.ncp == nch->ncp) + return(1); + return(0); +} + void -cache_clrmountpt(struct namecache *ncp) +cache_clrmountpt(struct nchandle *nch) { - if (ncp->nc_parent) - ncp->nc_parent->nc_flag &= ~NCF_MOUNTEDHERE; - ncp->nc_mount = NULL; + int count; + + count = mountlist_scan(cache_clrmountpt_callback, nch, + MNTSCAN_FORWARD|MNTSCAN_NOBUSY); + if (count == 0) + nch->ncp->nc_flag &= ~NCF_ISMOUNTPT; } /* @@ -690,10 +784,11 @@ struct cinvtrack { int depth; }; -static int cache_inval_internal(struct namecache *, int, struct cinvtrack *); +static int _cache_inval_internal(struct namecache *, int, struct cinvtrack *); +static int -cache_inval(struct namecache *ncp, int flags) +_cache_inval(struct namecache *ncp, int flags) { struct cinvtrack track; struct namecache *ncp2; @@ -703,26 +798,32 @@ cache_inval(struct namecache *ncp, int flags) track.resume_ncp = NULL; for (;;) { - r = cache_inval_internal(ncp, flags, &track); + r = _cache_inval_internal(ncp, flags, &track); if (track.resume_ncp == NULL) break; printf("Warning: deep namecache recursion at %s\n", ncp->nc_name); - cache_unlock(ncp); + _cache_unlock(ncp); while ((ncp2 = track.resume_ncp) != NULL) { track.resume_ncp = NULL; - cache_lock(ncp2); - cache_inval_internal(ncp2, flags & ~CINV_DESTROY, + _cache_lock(ncp2); + _cache_inval_internal(ncp2, flags & ~CINV_DESTROY, &track); - cache_put(ncp2); + _cache_put(ncp2); } - cache_lock(ncp); + _cache_lock(ncp); } return(r); } +int +cache_inval(struct nchandle *nch, int flags) +{ + return(_cache_inval(nch->ncp, flags)); +} + static int -cache_inval_internal(struct namecache *ncp, int flags, struct cinvtrack *track) +_cache_inval_internal(struct namecache *ncp, int flags, struct cinvtrack *track) { struct namecache *kid; struct namecache *nextkid; @@ -730,7 +831,7 @@ cache_inval_internal(struct namecache *ncp, int flags, struct cinvtrack *track) KKASSERT(ncp->nc_exlocks); - cache_setunresolved(ncp); + _cache_setunresolved(ncp); if (flags & CINV_DESTROY) ncp->nc_flag |= NCF_DESTROYED; @@ -739,30 +840,30 @@ cache_inval_internal(struct namecache *ncp, int flags, struct cinvtrack *track) ) { if (++track->depth > MAX_RECURSION_DEPTH) { track->resume_ncp = ncp; - cache_hold(ncp); + _cache_hold(ncp); ++rcnt; } - cache_hold(kid); - cache_unlock(ncp); + _cache_hold(kid); + _cache_unlock(ncp); while (kid) { if (track->resume_ncp) { - cache_drop(kid); + _cache_drop(kid); break; } if ((nextkid = TAILQ_NEXT(kid, nc_entry)) != NULL) - cache_hold(nextkid); + _cache_hold(nextkid); if ((kid->nc_flag & NCF_UNRESOLVED) == 0 || TAILQ_FIRST(&kid->nc_list) ) { - cache_lock(kid); - rcnt += cache_inval_internal(kid, flags & ~CINV_DESTROY, track); - cache_unlock(kid); + _cache_lock(kid); + rcnt += _cache_inval_internal(kid, flags & ~CINV_DESTROY, track); + _cache_unlock(kid); } - cache_drop(kid); + _cache_drop(kid); kid = nextkid; } --track->depth; - cache_lock(ncp); + _cache_lock(ncp); } /* @@ -796,27 +897,27 @@ cache_inval_vp(struct vnode *vp, int flags) restart: ncp = TAILQ_FIRST(&vp->v_namecache); if (ncp) - cache_hold(ncp); + _cache_hold(ncp); while (ncp) { /* loop entered with ncp held */ if ((next = TAILQ_NEXT(ncp, nc_vnode)) != NULL) - cache_hold(next); - cache_lock(ncp); + _cache_hold(next); + _cache_lock(ncp); if (ncp->nc_vp != vp) { printf("Warning: cache_inval_vp: race-A detected on " "%s\n", ncp->nc_name); - cache_put(ncp); + _cache_put(ncp); if (next) - cache_drop(next); + _cache_drop(next); goto restart; } - cache_inval(ncp, flags); - cache_put(ncp); /* also releases reference */ + _cache_inval(ncp, flags); + _cache_put(ncp); /* also releases reference */ ncp = next; if (ncp && ncp->nc_vp != vp) { printf("Warning: cache_inval_vp: race-B detected on " "%s\n", ncp->nc_name); - cache_drop(ncp); + _cache_drop(ncp); goto restart; } } @@ -841,29 +942,31 @@ restart: * back out. An rm -rf can cause this situation to occur. */ void -cache_rename(struct namecache *fncp, struct namecache *tncp) +cache_rename(struct nchandle *fnch, struct nchandle *tnch) { + struct namecache *fncp = fnch->ncp; + struct namecache *tncp = tnch->ncp; struct namecache *scan; int didwarn = 0; - cache_setunresolved(fncp); - cache_setunresolved(tncp); - while (cache_inval(tncp, CINV_CHILDREN) != 0) { + _cache_setunresolved(fncp); + _cache_setunresolved(tncp); + while (_cache_inval(tncp, CINV_CHILDREN) != 0) { if (didwarn++ % 10 == 0) { printf("Warning: cache_rename: race during " "rename %s->%s\n", fncp->nc_name, tncp->nc_name); } tsleep(tncp, 0, "mvrace", hz / 10); - cache_setunresolved(tncp); + _cache_setunresolved(tncp); } while ((scan = TAILQ_FIRST(&fncp->nc_list)) != NULL) { - cache_hold(scan); + _cache_hold(scan); cache_unlink_parent(scan); cache_link_parent(scan, tncp); if (scan->nc_flag & NCF_HASHED) - cache_rehash(scan); - cache_drop(scan); + _cache_rehash(scan); + _cache_drop(scan); } } @@ -886,18 +989,20 @@ cache_rename(struct namecache *fncp, struct namecache *tncp) * contents of ncp->nc_vp. */ int -cache_vget(struct namecache *ncp, struct ucred *cred, +cache_vget(struct nchandle *nch, struct ucred *cred, int lk_type, struct vnode **vpp) { + struct namecache *ncp; struct vnode *vp; int error; + ncp = nch->ncp; again: vp = NULL; if (ncp->nc_flag & NCF_UNRESOLVED) { - cache_lock(ncp); - error = cache_resolve(ncp, cred); - cache_unlock(ncp); + _cache_lock(ncp); + error = cache_resolve(nch, cred); + _cache_unlock(ncp); } else { error = 0; } @@ -909,9 +1014,9 @@ again: */ if (vp->v_flag & VRECLAIMED) { printf("Warning: vnode reclaim race detected in cache_vget on %p (%s)\n", vp, ncp->nc_name); - cache_lock(ncp); - cache_setunresolved(ncp); - cache_unlock(ncp); + _cache_lock(ncp); + _cache_setunresolved(ncp); + _cache_unlock(ncp); goto again; } error = vget(vp, lk_type); @@ -933,17 +1038,20 @@ again: } int -cache_vref(struct namecache *ncp, struct ucred *cred, struct vnode **vpp) +cache_vref(struct nchandle *nch, struct ucred *cred, struct vnode **vpp) { + struct namecache *ncp; struct vnode *vp; int error; + ncp = nch->ncp; + again: vp = NULL; if (ncp->nc_flag & NCF_UNRESOLVED) { - cache_lock(ncp); - error = cache_resolve(ncp, cred); - cache_unlock(ncp); + _cache_lock(ncp); + error = cache_resolve(nch, cred); + _cache_unlock(ncp); } else { error = 0; } @@ -958,9 +1066,9 @@ again: */ if (vp->v_flag & VRECLAIMED) { printf("Warning: vnode reclaim race detected on cache_vref %p (%s)\n", vp, ncp->nc_name); - cache_lock(ncp); - cache_setunresolved(ncp); - cache_unlock(ncp); + _cache_lock(ncp); + _cache_setunresolved(ncp); + _cache_unlock(ncp); goto again; } vref_initial(vp, 1); @@ -991,10 +1099,13 @@ again: * hierarchy. */ void -cache_update_fsmid(struct namecache *ncp) +cache_update_fsmid(struct nchandle *nch) { - struct vnode *vp; + struct namecache *ncp; struct namecache *scan; + struct vnode *vp; + + ncp = nch->ncp; /* * Warning: even if we get a non-NULL vp it could still be in the @@ -1095,20 +1206,21 @@ cache_sync_fsmid_vp(struct vnode *vp) * the makeit variable. */ -static int cache_inefficient_scan(struct namecache *ncp, struct ucred *cred, +static int cache_inefficient_scan(struct nchandle *nch, struct ucred *cred, struct vnode *dvp); static int cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, struct vnode **saved_dvp); -struct namecache * -cache_fromdvp(struct vnode *dvp, struct ucred *cred, int makeit) +int +cache_fromdvp(struct vnode *dvp, struct ucred *cred, int makeit, + struct nchandle *nch) { - struct namecache *ncp; struct vnode *saved_dvp; struct vnode *pvp; int error; - ncp = NULL; + nch->ncp = NULL; + nch->mount = dvp->v_mount; saved_dvp = NULL; /* @@ -1116,15 +1228,15 @@ cache_fromdvp(struct vnode *dvp, struct ucred *cred, int makeit) * to be exercised. */ if (ncvp_debug >= 3 && makeit && TAILQ_FIRST(&dvp->v_namecache)) { - ncp = TAILQ_FIRST(&dvp->v_namecache); - printf("cache_fromdvp: forcing %s\n", ncp->nc_name); + nch->ncp = TAILQ_FIRST(&dvp->v_namecache); + printf("cache_fromdvp: forcing %s\n", nch->ncp->nc_name); goto force; } /* * Loop until resolution, inside code will break out on error. */ - while ((ncp = TAILQ_FIRST(&dvp->v_namecache)) == NULL && makeit) { + while ((nch->ncp = TAILQ_FIRST(&dvp->v_namecache)) == NULL && makeit) { force: /* * If dvp is the root of its filesystem it should already @@ -1132,9 +1244,9 @@ force: * effect of the mount, but it may have been disassociated. */ if (dvp->v_flag & VROOT) { - ncp = cache_get(dvp->v_mount->mnt_ncp); - error = cache_resolve_mp(ncp); - cache_put(ncp); + nch->ncp = _cache_get(nch->mount->mnt_ncmountpt.ncp); + error = cache_resolve_mp(nch->mount); + _cache_put(nch->ncp); if (ncvp_debug) { printf("cache_fromdvp: resolve root of mount %p error %d", dvp->v_mount, error); @@ -1142,7 +1254,7 @@ force: if (error) { if (ncvp_debug) printf(" failed\n"); - ncp = NULL; + nch->ncp = NULL; break; } if (ncvp_debug) @@ -1179,9 +1291,9 @@ force: /* * Reuse makeit as a recursion depth counter. */ - ncp = cache_fromdvp(pvp, cred, makeit + 1); + cache_fromdvp(pvp, cred, makeit + 1, nch); vrele(pvp); - if (ncp == NULL) + if (nch->ncp == NULL) break; /* @@ -1191,24 +1303,30 @@ force: * * ncp and dvp are both held but not locked. */ - error = cache_inefficient_scan(ncp, cred, dvp); - cache_drop(ncp); + error = cache_inefficient_scan(nch, cred, dvp); + _cache_drop(nch->ncp); if (error) { printf("cache_fromdvp: scan %p (%s) failed on dvp=%p\n", - pvp, ncp->nc_name, dvp); - ncp = NULL; + pvp, nch->ncp->nc_name, dvp); + nch->ncp = NULL; break; } if (ncvp_debug) { printf("cache_fromdvp: scan %p (%s) succeeded\n", - pvp, ncp->nc_name); + pvp, nch->ncp->nc_name); } } - if (ncp) - cache_hold(ncp); + + /* + * hold it for real so the mount gets a ref + */ + if (nch->ncp) + cache_hold(nch); if (saved_dvp) vrele(saved_dvp); - return (ncp); + if (nch->ncp) + return (0); + return (EINVAL); } /* @@ -1220,7 +1338,7 @@ int cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, struct vnode **saved_dvp) { - struct namecache *ncp; + struct nchandle nch; struct vnode *pvp; int error; static time_t last_fromdvp_report; @@ -1230,6 +1348,8 @@ cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, * can resolve in the namecache. */ vref(dvp); + nch.mount = dvp->v_mount; + for (;;) { error = vop_nlookupdotdot(*dvp->v_ops, dvp, &pvp, cred); if (error) { @@ -1237,18 +1357,18 @@ cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, return (error); } vn_unlock(pvp); - if ((ncp = TAILQ_FIRST(&pvp->v_namecache)) != NULL) { - cache_hold(ncp); + if ((nch.ncp = TAILQ_FIRST(&pvp->v_namecache)) != NULL) { + _cache_hold(nch.ncp); vrele(pvp); break; } if (pvp->v_flag & VROOT) { - ncp = cache_get(pvp->v_mount->mnt_ncp); - error = cache_resolve_mp(ncp); - cache_unlock(ncp); + nch.ncp = _cache_get(pvp->v_mount->mnt_ncmountpt.ncp); + error = cache_resolve_mp(nch.mount); + _cache_unlock(nch.ncp); vrele(pvp); if (error) { - cache_drop(ncp); + _cache_drop(nch.ncp); vrele(dvp); return (error); } @@ -1260,9 +1380,9 @@ cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, if (last_fromdvp_report != time_second) { last_fromdvp_report = time_second; printf("Warning: extremely inefficient path resolution on %s\n", - ncp->nc_name); + nch.ncp->nc_name); } - error = cache_inefficient_scan(ncp, cred, dvp); + error = cache_inefficient_scan(&nch, cred, dvp); /* * Hopefully dvp now has a namecache record associated with it. @@ -1302,11 +1422,11 @@ cache_fromdvp_try(struct vnode *dvp, struct ucred *cred, * algorithms. */ static int -cache_inefficient_scan(struct namecache *ncp, struct ucred *cred, +cache_inefficient_scan(struct nchandle *nch, struct ucred *cred, struct vnode *dvp) { struct nlcomponent nlc; - struct namecache *rncp; + struct nchandle rncp; struct dirent *den; struct vnode *pvp; struct vattr vat; @@ -1321,14 +1441,14 @@ cache_inefficient_scan(struct namecache *ncp, struct ucred *cred, vat.va_blocksize = 0; if ((error = VOP_GETATTR(dvp, &vat)) != 0) return (error); - if ((error = cache_vref(ncp, cred, &pvp)) != 0) + if ((error = cache_vref(nch, cred, &pvp)) != 0) return (error); if (ncvp_debug) printf("inefficient_scan: directory iosize %ld vattr fileid = %ld\n", vat.va_blocksize, (long)vat.va_fileid); if ((blksize = vat.va_blocksize) == 0) blksize = DEV_BSIZE; rbuf = kmalloc(blksize, M_TEMP, M_WAITOK); - rncp = NULL; + rncp.ncp = NULL; eofflag = 0; uio.uio_offset = 0; @@ -1360,43 +1480,43 @@ again: if (ncvp_debug) { printf("cache_inefficient_scan: " "MATCHED inode %ld path %s/%*.*s\n", - vat.va_fileid, ncp->nc_name, + vat.va_fileid, nch->ncp->nc_name, den->d_namlen, den->d_namlen, den->d_name); } nlc.nlc_nameptr = den->d_name; nlc.nlc_namelen = den->d_namlen; - rncp = cache_nlookup(ncp, &nlc); - KKASSERT(rncp != NULL); + rncp = cache_nlookup(nch, &nlc); + KKASSERT(rncp.ncp != NULL); break; } bytes -= _DIRENT_DIRSIZ(den); den = _DIRENT_NEXT(den); } - if (rncp == NULL && eofflag == 0 && uio.uio_resid != blksize) + if (rncp.ncp == NULL && eofflag == 0 && uio.uio_resid != blksize) goto again; } vrele(pvp); - if (rncp) { - if (rncp->nc_flag & NCF_UNRESOLVED) { - cache_setvp(rncp, dvp); + if (rncp.ncp) { + if (rncp.ncp->nc_flag & NCF_UNRESOLVED) { + _cache_setvp(rncp.ncp, dvp); if (ncvp_debug >= 2) { printf("cache_inefficient_scan: setvp %s/%s = %p\n", - ncp->nc_name, rncp->nc_name, dvp); + nch->ncp->nc_name, rncp.ncp->nc_name, dvp); } } else { if (ncvp_debug >= 2) { printf("cache_inefficient_scan: setvp %s/%s already set %p/%p\n", - ncp->nc_name, rncp->nc_name, dvp, - rncp->nc_vp); + nch->ncp->nc_name, rncp.ncp->nc_name, dvp, + rncp.ncp->nc_vp); } } - if (rncp->nc_vp == NULL) - error = rncp->nc_error; - cache_put(rncp); + if (rncp.ncp->nc_vp == NULL) + error = rncp.ncp->nc_error; + _cache_put(rncp.ncp); } else { printf("cache_inefficient_scan: dvp %p NOT FOUND in %s\n", - dvp, ncp->nc_name); + dvp, nch->ncp->nc_name); error = ENOENT; } kfree(rbuf, M_TEMP); @@ -1427,7 +1547,7 @@ cache_zap(struct namecache *ncp) /* * Disassociate the vnode or negative cache ref and set NCF_UNRESOLVED. */ - cache_setunresolved(ncp); + _cache_setunresolved(ncp); /* * Try to scrap the entry and possibly tail-recurse on its parent. @@ -1455,7 +1575,7 @@ cache_zap(struct namecache *ncp) LIST_REMOVE(ncp, nc_hash); } if ((par = ncp->nc_parent) != NULL) { - par = cache_hold(par); + par = _cache_hold(par); TAILQ_REMOVE(&par->nc_list, ncp, nc_entry); ncp->nc_parent = NULL; if (par->nc_vp && TAILQ_EMPTY(&par->nc_list)) @@ -1468,7 +1588,7 @@ cache_zap(struct namecache *ncp) */ KKASSERT(ncp->nc_refs == 1); --numunres; - /* cache_unlock(ncp) not required */ + /* _cache_unlock(ncp) not required */ ncp->nc_refs = -1; /* safety */ if (ncp->nc_name) kfree(ncp->nc_name, M_VFSCACHE); @@ -1483,14 +1603,14 @@ cache_zap(struct namecache *ncp) if (ncp == NULL) return; if (ncp->nc_refs != 1) { - cache_drop(ncp); + _cache_drop(ncp); return; } KKASSERT(par->nc_exlocks == 0); - cache_lock(ncp); + _cache_lock(ncp); } done: - cache_unlock(ncp); + _cache_unlock(ncp); atomic_subtract_int(&ncp->nc_refs, 1); } @@ -1529,7 +1649,7 @@ cache_hysteresis(void) * Lookup an entry in the cache. A locked, referenced, non-NULL * entry is *always* returned, even if the supplied component is illegal. * The resulting namecache entry should be returned to the system with - * cache_put() or cache_unlock() + cache_drop(). + * cache_put() or _cache_unlock() + cache_drop(). * * namecache locks are recursive but care must be taken to avoid lock order * reversals. @@ -1554,9 +1674,10 @@ cache_hysteresis(void) * responsible for resolving the namecache chain top-down. This API * specifically allows whole chains to be created in an unresolved state. */ -struct namecache * -cache_nlookup(struct namecache *par, struct nlcomponent *nlc) +struct nchandle +cache_nlookup(struct nchandle *par_nch, struct nlcomponent *nlc) { + struct nchandle nch; struct namecache *ncp; struct namecache *new_ncp; struct nchashhead *nchpp; @@ -1570,7 +1691,7 @@ cache_nlookup(struct namecache *par, struct nlcomponent *nlc) * Try to locate an existing entry */ hash = fnv_32_buf(nlc->nlc_nameptr, nlc->nlc_namelen, FNV1_32_INIT); - hash = fnv_32_buf(&par, sizeof(par), hash); + hash = fnv_32_buf(&par_nch->ncp, sizeof(par_nch->ncp), hash); new_ncp = NULL; restart: LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { @@ -1584,7 +1705,7 @@ restart: (ncp->nc_flag & NCF_UNRESOLVED) == 0 && ncp->nc_exlocks == 0 ) { - cache_zap(cache_get(ncp)); + cache_zap(_cache_get(ncp)); goto restart; } @@ -1593,18 +1714,18 @@ restart: * UNRESOLVED entries may match, but DESTROYED entries * do not. */ - if (ncp->nc_parent == par && + if (ncp->nc_parent == par_nch->ncp && ncp->nc_nlen == nlc->nlc_namelen && bcmp(ncp->nc_name, nlc->nlc_nameptr, ncp->nc_nlen) == 0 && (ncp->nc_flag & NCF_DESTROYED) == 0 ) { - if (cache_get_nonblock(ncp) == 0) { + if (_cache_get_nonblock(ncp) == 0) { if (new_ncp) - cache_free(new_ncp); + _cache_free(new_ncp); goto found; } - cache_get(ncp); - cache_put(ncp); + _cache_get(ncp); + _cache_put(ncp); goto restart; } } @@ -1625,19 +1746,17 @@ restart: * Initialize as a new UNRESOLVED entry, lock (non-blocking), * and link to the parent. The mount point is usually inherited * from the parent unless this is a special case such as a mount - * point where nlc_namelen is 0. The caller is responsible for - * setting nc_mount in that case. If nlc_namelen is 0 nc_name will + * point where nlc_namelen is 0. If nlc_namelen is 0 nc_name will * be NULL. */ if (nlc->nlc_namelen) { bcopy(nlc->nlc_nameptr, ncp->nc_name, nlc->nlc_namelen); ncp->nc_name[nlc->nlc_namelen] = 0; - ncp->nc_mount = par->nc_mount; } nchpp = NCHHASH(hash); LIST_INSERT_HEAD(nchpp, ncp, nc_hash); ncp->nc_flag |= NCF_HASHED; - cache_link_parent(ncp, par); + cache_link_parent(ncp, par_nch->ncp); found: /* * stats and namecache size management @@ -1649,39 +1768,51 @@ found: else ++gd->gd_nchstats->ncs_neghits; cache_hysteresis(); - return(ncp); + nch.mount = par_nch->mount; + nch.ncp = ncp; + ++nch.mount->mnt_refs; + return(nch); } /* - * Locate the mount point under a namecache entry. We locate a special - * child ncp with a 0-length name and retrieve the mount point from it. + * The namecache entry is marked as being used as a mount point. + * Locate the mount if it is visible to the caller. */ -struct mount * -cache_findmount(struct namecache *par) +struct findmount_info { + struct mount *result; + struct mount *nch_mount; + struct namecache *nch_ncp; +}; + +static +int +cache_findmount_callback(struct mount *mp, void *data) { - struct namecache *ncp; - u_int32_t hash; + struct findmount_info *info = data; - hash = FNV1_32_INIT; /* special 0-length name */ - hash = fnv_32_buf(&par, sizeof(par), hash); - LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { - if (ncp->nc_nlen == 0 && (ncp->nc_flag & NCF_MOUNTPT)) - return(ncp->nc_mount); + /* + * Check the mount's mounted-on point against the passed nch. + */ + if (mp->mnt_ncmounton.mount == info->nch_mount && + mp->mnt_ncmounton.ncp == info->nch_ncp + ) { + info->result = mp; + return(-1); } - return(NULL); + return(0); } -/* - * Given a locked ncp, validate that the vnode, if present, is actually - * usable. If it is not usable set the ncp to an unresolved state. - */ -void -cache_validate(struct namecache *ncp) +struct mount * +cache_findmount(struct nchandle *nch) { - if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) { - if (ncp->nc_vp && (ncp->nc_vp->v_flag & VRECLAIMED)) - cache_setunresolved(ncp); - } + struct findmount_info info; + + info.result = NULL; + info.nch_mount = nch->mount; + info.nch_ncp = nch->ncp; + mountlist_scan(cache_findmount_callback, &info, + MNTSCAN_FORWARD|MNTSCAN_NOBUSY); + return(info.result); } /* @@ -1704,11 +1835,16 @@ cache_validate(struct namecache *ncp) * will be returned. */ int -cache_resolve(struct namecache *ncp, struct ucred *cred) +cache_resolve(struct nchandle *nch, struct ucred *cred) { struct namecache *par; + struct namecache *ncp; + struct nchandle nctmp; + struct mount *mp; int error; + ncp = nch->ncp; + mp = nch->mount; restart: /* * If the ncp is already resolved we have nothing to do. However, @@ -1717,7 +1853,7 @@ restart: */ if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) { if (ncp->nc_vp && (ncp->nc_vp->v_flag & VRECLAIMED)) - cache_setunresolved(ncp); + _cache_setunresolved(ncp); if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) return (ncp->nc_error); } @@ -1726,8 +1862,8 @@ restart: * Mount points need special handling because the parent does not * belong to the same filesystem as the ncp. */ - if (ncp->nc_flag & NCF_MOUNTPT) - return (cache_resolve_mp(ncp)); + if (ncp == mp->mnt_ncmountpt.ncp) + return (cache_resolve_mp(mp)); /* * We expect an unbroken chain of ncps to at least the mount point, @@ -1785,28 +1921,30 @@ restart: * be one of its parents. We resolve it anyway, the loop * will handle any moves. */ - cache_get(par); - if (par->nc_flag & NCF_MOUNTPT) { - cache_resolve_mp(par); + _cache_get(par); + if (par == nch->mount->mnt_ncmountpt.ncp) { + cache_resolve_mp(nch->mount); } else if (par->nc_parent->nc_vp == NULL) { printf("[diagnostic] cache_resolve: raced on %*.*s\n", par->nc_nlen, par->nc_nlen, par->nc_name); - cache_put(par); + _cache_put(par); continue; } else if (par->nc_flag & NCF_UNRESOLVED) { - par->nc_error = VOP_NRESOLVE(par, cred); + nctmp.mount = mp; + nctmp.ncp = par; + par->nc_error = VOP_NRESOLVE(&nctmp, cred); } if ((error = par->nc_error) != 0) { if (par->nc_error != EAGAIN) { printf("EXDEV case 3 %*.*s error %d\n", par->nc_nlen, par->nc_nlen, par->nc_name, par->nc_error); - cache_put(par); + _cache_put(par); return(error); } printf("[diagnostic] cache_resolve: EAGAIN par %p %*.*s\n", par, par->nc_nlen, par->nc_nlen, par->nc_name); } - cache_put(par); + _cache_put(par); /* loop */ } @@ -1818,8 +1956,9 @@ restart: * NOTE: in order to call VOP_NRESOLVE(), the parent of the passed * ncp must already be resolved. */ - KKASSERT((ncp->nc_flag & NCF_MOUNTPT) == 0); - ncp->nc_error = VOP_NRESOLVE(ncp, cred); + nctmp.mount = mp; + nctmp.ncp = ncp; + ncp->nc_error = VOP_NRESOLVE(&nctmp, cred); /*vop_nresolve(*ncp->nc_parent->nc_vp->v_ops, ncp, cred);*/ if (ncp->nc_error == EAGAIN) { printf("[diagnostic] cache_resolve: EAGAIN ncp %p %*.*s\n", @@ -1842,10 +1981,10 @@ restart: * the unlock we have to recheck the flags after we relock. */ static int -cache_resolve_mp(struct namecache *ncp) +cache_resolve_mp(struct mount *mp) { + struct namecache *ncp = mp->mnt_ncmountpt.ncp; struct vnode *vp; - struct mount *mp = ncp->nc_mount; int error; KKASSERT(mp != NULL); @@ -1857,15 +1996,15 @@ cache_resolve_mp(struct namecache *ncp) */ if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) { if (ncp->nc_vp && (ncp->nc_vp->v_flag & VRECLAIMED)) - cache_setunresolved(ncp); + _cache_setunresolved(ncp); } if (ncp->nc_flag & NCF_UNRESOLVED) { - cache_unlock(ncp); + _cache_unlock(ncp); while (vfs_busy(mp, 0)) ; error = VFS_ROOT(mp, &vp); - cache_lock(ncp); + _cache_lock(ncp); /* * recheck the ncp state after relocking. @@ -1873,11 +2012,11 @@ cache_resolve_mp(struct namecache *ncp) if (ncp->nc_flag & NCF_UNRESOLVED) { ncp->nc_error = error; if (error == 0) { - cache_setvp(ncp, vp); + _cache_setvp(ncp, vp); vput(vp); } else { printf("[diagnostic] cache_resolve_mp: failed to resolve mount %p\n", mp); - cache_setvp(ncp, NULL); + _cache_setvp(ncp, NULL); } } else if (error == 0) { vput(vp); @@ -1911,7 +2050,7 @@ cache_cleanneg(int count) } TAILQ_REMOVE(&ncneglist, ncp, nc_vnode); TAILQ_INSERT_TAIL(&ncneglist, ncp, nc_vnode); - if (cache_get_nonblock(ncp) == 0) + if (_cache_get_nonblock(ncp) == 0) cache_zap(ncp); --count; } @@ -1923,7 +2062,7 @@ cache_cleanneg(int count) * unhash the ncp if the ncp is no longer hashable. */ static void -cache_rehash(struct namecache *ncp) +_cache_rehash(struct namecache *ncp) { struct nchashhead *nchpp; u_int32_t hash; @@ -1965,15 +2104,14 @@ nchinit(void) * Called from start_init() to bootstrap the root filesystem. Returns * a referenced, unlocked namecache record. */ -struct namecache * -cache_allocroot(struct mount *mp, struct vnode *vp) +void +cache_allocroot(struct nchandle *nch, struct mount *mp, struct vnode *vp) { - struct namecache *ncp = cache_alloc(0); - - ncp->nc_flag |= NCF_MOUNTPT | NCF_ROOT; - ncp->nc_mount = mp; - cache_setvp(ncp, vp); - return(ncp); + nch->ncp = cache_alloc(0); + nch->mount = mp; + ++mp->mnt_refs; + if (vp) + _cache_setvp(nch->ncp, vp); } /* @@ -1987,20 +2125,22 @@ cache_allocroot(struct mount *mp, struct vnode *vp) * it must cache_hold() it. */ void -vfs_cache_setroot(struct vnode *nvp, struct namecache *ncp) +vfs_cache_setroot(struct vnode *nvp, struct nchandle *nch) { struct vnode *ovp; - struct namecache *oncp; + struct nchandle onch; ovp = rootvnode; - oncp = rootncp; + onch = rootnch; rootvnode = nvp; - rootncp = ncp; - + if (nch) + rootnch = *nch; + else + cache_zero(&rootnch); if (ovp) vrele(ovp); - if (oncp) - cache_drop(oncp); + if (onch.ncp) + cache_drop(&onch); } /* @@ -2032,6 +2172,8 @@ cache_purge(struct vnode *vp) * Since we need to check it anyway, we will flush all the invalid * entries at the same time. */ +#if 0 + void cache_purgevfs(struct mount *mp) { @@ -2044,22 +2186,24 @@ cache_purgevfs(struct mount *mp) for (nchpp = &nchashtbl[nchash]; nchpp >= nchashtbl; nchpp--) { ncp = LIST_FIRST(nchpp); if (ncp) - cache_hold(ncp); + _cache_hold(ncp); while (ncp) { nnp = LIST_NEXT(ncp, nc_hash); if (nnp) - cache_hold(nnp); + _cache_hold(nnp); if (ncp->nc_mount == mp) { - cache_lock(ncp); + _cache_lock(ncp); cache_zap(ncp); } else { - cache_drop(ncp); + _cache_drop(ncp); } ncp = nnp; } } } +#endif + /* * Create a new (theoretically) unique fsmid */ @@ -2118,7 +2262,7 @@ kern_getcwd(char *buf, size_t buflen, int *error) char *bp; int i, slash_prefixed; struct filedesc *fdp; - struct namecache *ncp; + struct nchandle nch; numcwdcalls++; bp = buf; @@ -2127,23 +2271,30 @@ kern_getcwd(char *buf, size_t buflen, int *error) fdp = p->p_fd; slash_prefixed = 0; - ncp = fdp->fd_ncdir; - while (ncp && ncp != fdp->fd_nrdir && (ncp->nc_flag & NCF_ROOT) == 0) { - if (ncp->nc_flag & NCF_MOUNTPT) { - if (ncp->nc_mount == NULL) { - *error = EBADF; /* forced unmount? */ - return(NULL); - } - ncp = ncp->nc_parent; + nch = fdp->fd_ncdir; + while (nch.ncp && (nch.ncp != fdp->fd_nrdir.ncp || + nch.mount != fdp->fd_nrdir.mount) + ) { + /* + * While traversing upwards if we encounter the root + * of the current mount we have to skip to the mount point + * in the underlying filesystem. + */ + if (nch.ncp == nch.mount->mnt_ncmountpt.ncp) { + nch = nch.mount->mnt_ncmounton; continue; } - for (i = ncp->nc_nlen - 1; i >= 0; i--) { + + /* + * Prepend the path segment + */ + for (i = nch.ncp->nc_nlen - 1; i >= 0; i--) { if (bp == buf) { numcwdfail4++; *error = ENOMEM; return(NULL); } - *--bp = ncp->nc_name[i]; + *--bp = nch.ncp->nc_name[i]; } if (bp == buf) { numcwdfail4++; @@ -2152,9 +2303,14 @@ kern_getcwd(char *buf, size_t buflen, int *error) } *--bp = '/'; slash_prefixed = 1; - ncp = ncp->nc_parent; + + /* + * Go up a directory. This isn't a mount point so we don't + * have to check again. + */ + nch.ncp = nch.ncp->nc_parent; } - if (ncp == NULL) { + if (nch.ncp == NULL) { numcwdfail2++; *error = ENOENT; return(NULL); @@ -2193,38 +2349,50 @@ STATNODE(numfullpathfail4); STATNODE(numfullpathfound); int -cache_fullpath(struct proc *p, struct namecache *ncp, char **retbuf, char **freebuf) +cache_fullpath(struct proc *p, struct nchandle *nchp, char **retbuf, char **freebuf) { char *bp, *buf; int i, slash_prefixed; - struct namecache *fd_nrdir; + struct nchandle fd_nrdir; + struct nchandle nch; numfullpathcalls--; + *retbuf = NULL; + *freebuf = NULL; + buf = kmalloc(MAXPATHLEN, M_TEMP, M_WAITOK); bp = buf + MAXPATHLEN - 1; *bp = '\0'; if (p != NULL) fd_nrdir = p->p_fd->fd_nrdir; else - fd_nrdir = NULL; + fd_nrdir = rootnch; slash_prefixed = 0; - while (ncp && ncp != fd_nrdir && (ncp->nc_flag & NCF_ROOT) == 0) { - if (ncp->nc_flag & NCF_MOUNTPT) { - if (ncp->nc_mount == NULL) { - kfree(buf, M_TEMP); - return(EBADF); - } - ncp = ncp->nc_parent; + nch = *nchp; + + while (nch.ncp && + (nch.ncp != fd_nrdir.ncp || nch.mount != fd_nrdir.mount) + ) { + /* + * While traversing upwards if we encounter the root + * of the current mount we have to skip to the mount point. + */ + if (nch.ncp == nch.mount->mnt_ncmountpt.ncp) { + nch = nch.mount->mnt_ncmounton; continue; } - for (i = ncp->nc_nlen - 1; i >= 0; i--) { + + /* + * Prepend the path segment + */ + for (i = nch.ncp->nc_nlen - 1; i >= 0; i--) { if (bp == buf) { numfullpathfail4++; kfree(buf, M_TEMP); return(ENOMEM); } - *--bp = ncp->nc_name[i]; + *--bp = nch.ncp->nc_name[i]; } if (bp == buf) { numfullpathfail4++; @@ -2233,18 +2401,19 @@ cache_fullpath(struct proc *p, struct namecache *ncp, char **retbuf, char **free } *--bp = '/'; slash_prefixed = 1; - ncp = ncp->nc_parent; + + /* + * Go up a directory. This isn't a mount point so we don't + * have to check again. + */ + nch.ncp = nch.ncp->nc_parent; } - if (ncp == NULL) { + if (nch.ncp == NULL) { numfullpathfail2++; kfree(buf, M_TEMP); return(ENOENT); } - if (p != NULL && (ncp->nc_flag & NCF_ROOT) && ncp != fd_nrdir) { - bp = buf + MAXPATHLEN - 1; - *bp = '\0'; - slash_prefixed = 0; - } + if (!slash_prefixed) { if (bp == buf) { numfullpathfail4++; @@ -2264,6 +2433,7 @@ int vn_fullpath(struct proc *p, struct vnode *vn, char **retbuf, char **freebuf) { struct namecache *ncp; + struct nchandle nch; numfullpathcalls++; if (disablefullpath) @@ -2285,5 +2455,7 @@ vn_fullpath(struct proc *p, struct vnode *vn, char **retbuf, char **freebuf) return (EINVAL); numfullpathcalls--; - return(cache_fullpath(p, ncp, retbuf, freebuf)); + nch.ncp = ncp;; + nch.mount = vn->v_mount; + return(cache_fullpath(p, &nch, retbuf, freebuf)); } diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c index d9ee84cc7b..85f75600dc 100644 --- a/sys/kern/vfs_conf.c +++ b/sys/kern/vfs_conf.c @@ -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.20 2006/09/10 01:26:39 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_conf.c,v 1.21 2006/10/27 04:56:31 dillon Exp $ */ /* @@ -72,7 +72,7 @@ MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); #define ROOTNAME "root_device" struct vnode *rootvnode; -struct namecache *rootncp; +struct nchandle rootnch; /* * The root specifiers we will try if RB_CDROM is specified. Note that diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 11c2559b47..be93ebdbe5 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -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.44 2006/10/26 02:27:19 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.45 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -153,7 +153,7 @@ vop_panic(struct vop_generic_args *ap) } /* - * vop_compat_resolve { struct namecache *a_ncp } XXX STOPGAP FUNCTION + * vop_compat_resolve { struct nchandle *a_nch } 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 @@ -183,12 +183,12 @@ vop_compat_nresolve(struct vop_nresolve_args *ap) int error; struct vnode *dvp; struct vnode *vp; + struct nchandle *nch; struct namecache *ncp; struct componentname cnp; - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -228,13 +228,13 @@ vop_compat_nresolve(struct vop_nresolve_args *ap) vrele(vp); } else if (error == 0) { KKASSERT(vp != NULL); - cache_setvp(ncp, vp); + cache_setvp(nch, vp); vrele(vp); } else if (error == ENOENT) { KKASSERT(vp == NULL); if (cnp.cn_flags & CNP_ISWHITEOUT) ncp->nc_flag |= NCF_WHITEOUT; - cache_setvp(ncp, NULL); + cache_setvp(nch, NULL); } vrele(dvp); return (error); @@ -300,7 +300,7 @@ vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap) } /* - * vop_compat_ncreate { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct vnode *a_vpp, * struct ucred *a_cred, * struct vattr *a_vap } @@ -314,6 +314,7 @@ vop_compat_ncreate(struct vop_ncreate_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; int error; @@ -321,9 +322,8 @@ vop_compat_ncreate(struct vop_ncreate_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -364,8 +364,8 @@ vop_compat_ncreate(struct vop_ncreate_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, *ap->a_vpp); + cache_setunresolved(nch); + cache_setvp(nch, *ap->a_vpp); } } else { if (error == 0) { @@ -382,7 +382,7 @@ vop_compat_ncreate(struct vop_ncreate_args *ap) } /* - * vop_compat_nmkdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct vnode *a_vpp, * struct ucred *a_cred, * struct vattr *a_vap } @@ -396,6 +396,7 @@ vop_compat_nmkdir(struct vop_nmkdir_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; int error; @@ -403,9 +404,8 @@ vop_compat_nmkdir(struct vop_nmkdir_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -446,8 +446,8 @@ vop_compat_nmkdir(struct vop_nmkdir_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, *ap->a_vpp); + cache_setunresolved(nch); + cache_setvp(nch, *ap->a_vpp); } } else { if (error == 0) { @@ -464,7 +464,7 @@ vop_compat_nmkdir(struct vop_nmkdir_args *ap) } /* - * vop_compat_nmknod { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct vnode *a_vpp, * struct ucred *a_cred, * struct vattr *a_vap } @@ -478,6 +478,7 @@ vop_compat_nmknod(struct vop_nmknod_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; int error; @@ -485,9 +486,8 @@ vop_compat_nmknod(struct vop_nmknod_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -528,8 +528,8 @@ vop_compat_nmknod(struct vop_nmknod_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, *ap->a_vpp); + cache_setunresolved(nch); + cache_setvp(nch, *ap->a_vpp); } } else { if (error == 0) { @@ -546,7 +546,7 @@ vop_compat_nmknod(struct vop_nmknod_args *ap) } /* - * vop_compat_nlink { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct vnode *a_vp, * struct ucred *a_cred } * @@ -558,6 +558,7 @@ vop_compat_nlink(struct vop_nlink_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; struct vnode *tvp; @@ -566,9 +567,8 @@ vop_compat_nlink(struct vop_nlink_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -609,8 +609,8 @@ vop_compat_nlink(struct vop_nlink_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, ap->a_vp); + cache_setunresolved(nch); + cache_setvp(nch, ap->a_vp); } } else { if (error == 0) { @@ -629,6 +629,7 @@ vop_compat_nsymlink(struct vop_nsymlink_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; struct vnode *vp; @@ -638,9 +639,8 @@ vop_compat_nsymlink(struct vop_nsymlink_args *ap) * Sanity checks, get a locked directory vnode. */ *ap->a_vpp = NULL; - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -681,8 +681,8 @@ vop_compat_nsymlink(struct vop_nsymlink_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, vp); + cache_setunresolved(nch); + cache_setvp(nch, vp); *ap->a_vpp = vp; } } else { @@ -700,7 +700,7 @@ vop_compat_nsymlink(struct vop_nsymlink_args *ap) } /* - * vop_compat_nwhiteout { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct ucred *a_cred, * int a_flags } * @@ -715,6 +715,7 @@ vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; struct vnode *vp; @@ -723,9 +724,8 @@ vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -771,7 +771,7 @@ vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags); if (error == 0) - cache_setunresolved(ncp); + cache_setunresolved(nch); } else { if (error == 0) { vput(vp); @@ -796,7 +796,7 @@ vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) /* - * vop_compat_nremove { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct ucred *a_cred } */ int @@ -804,6 +804,7 @@ vop_compat_nremove(struct vop_nremove_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; struct vnode *vp; @@ -812,9 +813,8 @@ vop_compat_nremove(struct vop_nremove_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -853,8 +853,8 @@ vop_compat_nremove(struct vop_nremove_args *ap) KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_REMOVE(dvp, vp, &cnp); if (error == 0) { - cache_setunresolved(ncp); - cache_setvp(ncp, NULL); + cache_setunresolved(nch); + cache_setvp(nch, NULL); cache_inval_vp(vp, CINV_DESTROY); } } @@ -871,7 +871,7 @@ vop_compat_nremove(struct vop_nremove_args *ap) } /* - * vop_compat_nrmdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION + * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION * struct ucred *a_cred } */ int @@ -879,6 +879,7 @@ vop_compat_nrmdir(struct vop_nrmdir_args *ap) { struct thread *td = curthread; struct componentname cnp; + struct nchandle *nch; struct namecache *ncp; struct vnode *dvp; struct vnode *vp; @@ -887,9 +888,8 @@ vop_compat_nrmdir(struct vop_nrmdir_args *ap) /* * Sanity checks, get a locked directory vnode. */ - ncp = ap->a_ncp; /* locked namecache node */ - if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + nch = ap->a_nch; /* locked namecache node */ + ncp = nch->ncp; if (ncp->nc_parent == NULL) return(EPERM); if ((dvp = ncp->nc_parent->nc_vp) == NULL) @@ -939,7 +939,7 @@ vop_compat_nrmdir(struct vop_nrmdir_args *ap) * back out. */ if (error == 0) { - cache_inval(ncp, CINV_DESTROY); + cache_inval(nch, CINV_DESTROY); cache_inval_vp(vp, CINV_DESTROY); } } @@ -956,8 +956,8 @@ vop_compat_nrmdir(struct vop_nrmdir_args *ap) } /* - * vop_compat_nrename { struct namecache *a_fncp, XXX STOPGAP FUNCTION - * struct namecache *a_tncp, + * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION + * struct nchandle *a_tnch, * struct ucred *a_cred } * * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that @@ -971,6 +971,8 @@ vop_compat_nrename(struct vop_nrename_args *ap) struct thread *td = curthread; struct componentname fcnp; struct componentname tcnp; + struct nchandle *fnch; + struct nchandle *tnch; struct namecache *fncp; struct namecache *tncp; struct vnode *fdvp, *fvp; @@ -980,9 +982,8 @@ vop_compat_nrename(struct vop_nrename_args *ap) /* * Sanity checks, get referenced vnodes representing the source. */ - fncp = ap->a_fncp; /* locked namecache node */ - if (fncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - return(EPERM); + fnch = ap->a_fnch; /* locked namecache node */ + fncp = fnch->ncp; if (fncp->nc_parent == NULL) return(EPERM); if ((fdvp = fncp->nc_parent->nc_vp) == NULL) @@ -1039,9 +1040,8 @@ vop_compat_nrename(struct vop_nrename_args *ap) * in CREATE mode so it places the required information in the * directory inode. */ - tncp = ap->a_tncp; /* locked namecache node */ - if (tncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ - error = EPERM; + tnch = ap->a_tnch; /* locked namecache node */ + tncp = tnch->ncp; if (tncp->nc_parent == NULL) error = EPERM; if ((tdvp = tncp->nc_parent->nc_vp) == NULL) @@ -1083,8 +1083,8 @@ vop_compat_nrename(struct vop_nrename_args *ap) KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); if (error == 0) { - cache_rename(fncp, tncp); - cache_setvp(tncp, fvp); + cache_rename(fnch, tnch); + cache_setvp(tnch, fvp); } } else if (error == 0) { /* @@ -1094,8 +1094,8 @@ vop_compat_nrename(struct vop_nrename_args *ap) KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); if (error == 0) { - cache_rename(fncp, tncp); - cache_setvp(tncp, fvp); + cache_rename(fnch, tnch); + cache_setvp(tnch, fvp); } } else { vrele(fdvp); diff --git a/sys/kern/vfs_jops.c b/sys/kern/vfs_jops.c index 1c5f5afb62..a3b4046c9c 100644 --- a/sys/kern/vfs_jops.c +++ b/sys/kern/vfs_jops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_jops.c,v 1.31 2006/09/30 21:10:19 swildner Exp $ + * $DragonFly: src/sys/kern/vfs_jops.c,v 1.32 2006/10/27 04:56:31 dillon Exp $ */ /* * Each mount point may have zero or more independantly configured journals @@ -1035,7 +1035,7 @@ journal_setextattr(struct vop_setextattr_args *ap) } /* - * Journal vop_ncreate { a_ncp, a_vpp, a_cred, a_vap } + * Journal vop_ncreate { a_nch, a_vpp, a_cred, a_vap } */ static int @@ -1054,7 +1054,7 @@ journal_ncreate(struct vop_ncreate_args *ap) if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); if (*ap->a_vpp) jrecord_write_vnode_ref(jrec, *ap->a_vpp); save = jrecord_push(jrec, JTYPE_REDO); @@ -1067,7 +1067,7 @@ journal_ncreate(struct vop_ncreate_args *ap) } /* - * Journal vop_nmknod { a_ncp, a_vpp, a_cred, a_vap } + * Journal vop_nmknod { a_nch, a_vpp, a_cred, a_vap } */ static int @@ -1086,7 +1086,7 @@ journal_nmknod(struct vop_nmknod_args *ap) if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); save = jrecord_push(jrec, JTYPE_REDO); jrecord_write_vattr(jrec, ap->a_vap); jrecord_pop(jrec, save); @@ -1099,7 +1099,7 @@ journal_nmknod(struct vop_nmknod_args *ap) } /* - * Journal vop_nlink { a_ncp, a_vp, a_cred } + * Journal vop_nlink { a_nch, a_vp, a_cred } */ static int @@ -1118,12 +1118,12 @@ journal_nlink(struct vop_nlink_args *ap) if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); /* XXX PATH to VP and inode number */ /* XXX this call may not record the correct path when * multiple paths are available */ save = jrecord_push(jrec, JTYPE_REDO); - jrecord_write_vnode_link(jrec, ap->a_vp, ap->a_ncp); + jrecord_write_vnode_link(jrec, ap->a_vp, ap->a_nch->ncp); jrecord_pop(jrec, save); } } @@ -1132,7 +1132,7 @@ journal_nlink(struct vop_nlink_args *ap) } /* - * Journal vop_symlink { a_ncp, a_vpp, a_cred, a_vap, a_target } + * Journal vop_symlink { a_nch, a_vpp, a_cred, a_vap, a_target } */ static int @@ -1151,7 +1151,7 @@ journal_nsymlink(struct vop_nsymlink_args *ap) if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); save = jrecord_push(jrec, JTYPE_REDO); jrecord_leaf(jrec, JLEAF_SYMLINKDATA, ap->a_target, strlen(ap->a_target)); @@ -1165,7 +1165,7 @@ journal_nsymlink(struct vop_nsymlink_args *ap) } /* - * Journal vop_nwhiteout { a_ncp, a_cred, a_flags } + * Journal vop_nwhiteout { a_nch, a_cred, a_flags } */ static int @@ -1183,7 +1183,7 @@ journal_nwhiteout(struct vop_nwhiteout_args *ap) if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); } } jreclist_done(mp, &jreclist, error); @@ -1191,7 +1191,7 @@ journal_nwhiteout(struct vop_nwhiteout_args *ap) } /* - * Journal vop_nremove { a_ncp, a_cred } + * Journal vop_nremove { a_nch, a_cred } */ static int @@ -1205,16 +1205,16 @@ journal_nremove(struct vop_nremove_args *ap) mp = ap->a_head.a_ops->head.vv_mount; if (jreclist_init(mp, &jreclist, &jreccache, JTYPE_REMOVE) && - ap->a_ncp->nc_vp + ap->a_nch->ncp->nc_vp ) { - jreclist_undo_file(&jreclist, ap->a_ncp->nc_vp, + jreclist_undo_file(&jreclist, ap->a_nch->ncp->nc_vp, JRUNDO_ALL|JRUNDO_GETVP|JRUNDO_CONDLINK, 0, -1); } error = vop_journal_operate_ap(&ap->a_head); if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); } } jreclist_done(mp, &jreclist, error); @@ -1222,7 +1222,7 @@ journal_nremove(struct vop_nremove_args *ap) } /* - * Journal vop_nmkdir { a_ncp, a_vpp, a_cred, a_vap } + * Journal vop_nmkdir { a_nch, a_vpp, a_cred, a_vap } */ static int @@ -1244,10 +1244,10 @@ journal_nmkdir(struct vop_nmkdir_args *ap) jrecord_write_audit(jrec); } #endif - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); jrecord_write_cred(jrec, NULL, ap->a_cred); jrecord_write_vattr(jrec, ap->a_vap); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); if (*ap->a_vpp) jrecord_write_vnode_ref(jrec, *ap->a_vpp); } @@ -1257,7 +1257,7 @@ journal_nmkdir(struct vop_nmkdir_args *ap) } /* - * Journal vop_nrmdir { a_ncp, a_cred } + * Journal vop_nrmdir { a_nch, a_cred } */ static int @@ -1271,14 +1271,14 @@ journal_nrmdir(struct vop_nrmdir_args *ap) mp = ap->a_head.a_ops->head.vv_mount; if (jreclist_init(mp, &jreclist, &jreccache, JTYPE_RMDIR)) { - jreclist_undo_file(&jreclist, ap->a_ncp->nc_vp, + jreclist_undo_file(&jreclist, ap->a_nch->ncp->nc_vp, JRUNDO_VATTR|JRUNDO_GETVP, 0, 0); } error = vop_journal_operate_ap(&ap->a_head); if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_ncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_nch->ncp); } } jreclist_done(mp, &jreclist, error); @@ -1286,7 +1286,7 @@ journal_nrmdir(struct vop_nrmdir_args *ap) } /* - * Journal vop_nrename { a_fncp, a_tncp, a_cred } + * Journal vop_nrename { a_fnch, a_tnch, a_cred } */ static int @@ -1300,17 +1300,17 @@ journal_nrename(struct vop_nrename_args *ap) mp = ap->a_head.a_ops->head.vv_mount; if (jreclist_init(mp, &jreclist, &jreccache, JTYPE_RENAME) && - ap->a_tncp->nc_vp + ap->a_tnch->ncp->nc_vp ) { - jreclist_undo_file(&jreclist, ap->a_tncp->nc_vp, + jreclist_undo_file(&jreclist, ap->a_tnch->ncp->nc_vp, JRUNDO_ALL|JRUNDO_GETVP|JRUNDO_CONDLINK, 0, -1); } error = vop_journal_operate_ap(&ap->a_head); if (error == 0) { TAILQ_FOREACH(jrec, &jreclist.list, user_entry) { jrecord_write_cred(jrec, NULL, ap->a_cred); - jrecord_write_path(jrec, JLEAF_PATH1, ap->a_fncp); - jrecord_write_path(jrec, JLEAF_PATH2, ap->a_tncp); + jrecord_write_path(jrec, JLEAF_PATH1, ap->a_fnch->ncp); + jrecord_write_path(jrec, JLEAF_PATH2, ap->a_tnch->ncp); } } jreclist_done(mp, &jreclist, error); diff --git a/sys/kern/vfs_journal.c b/sys/kern/vfs_journal.c index 61095cdc99..1e790b89ed 100644 --- a/sys/kern/vfs_journal.c +++ b/sys/kern/vfs_journal.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_journal.c,v 1.28 2006/09/05 00:55:45 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_journal.c,v 1.29 2006/10/27 04:56:31 dillon Exp $ */ /* * The journaling protocol is intended to evolve into a two-way stream @@ -1151,13 +1151,14 @@ jrecord_write_path(struct jrecord *jrec, int16_t rectype, struct namecache *ncp) /* * Pass 1 - figure out the number of bytes required. Include terminating * \0 on last element and '/' separator on other elements. + * + * The namecache topology terminates at the root of the filesystem + * (the normal lookup code would then continue by using the mount + * structure to figure out what it was mounted on). */ again: pathlen = 0; - for (scan = ncp; - scan && (scan->nc_flag & NCF_MOUNTPT) == 0; - scan = scan->nc_parent - ) { + for (scan = ncp; scan; scan = scan->nc_parent) { pathlen += scan->nc_nlen + 1; } @@ -1170,10 +1171,7 @@ again: * Pass 2 - generate the path buffer */ index = pathlen; - for (scan = ncp; - scan && (scan->nc_flag & NCF_MOUNTPT) == 0; - scan = scan->nc_parent - ) { + for (scan = ncp; scan; scan = scan->nc_parent) { if (scan->nc_nlen >= index) { if (base != buf) kfree(base, M_TEMP); diff --git a/sys/kern/vfs_nlookup.c b/sys/kern/vfs_nlookup.c index 9855f19df4..79f032de72 100644 --- a/sys/kern/vfs_nlookup.c +++ b/sys/kern/vfs_nlookup.c @@ -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.19 2006/09/19 16:06:11 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_nlookup.c,v 1.20 2006/10/27 04:56:31 dillon Exp $ */ /* * nlookup() is the 'new' namei interface. Rather then return directory and @@ -109,15 +109,15 @@ nlookup_init(struct nlookupdata *nd, if (error == 0) { 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); + cache_copy(&p->p_fd->fd_ncdir, &nd->nl_nch); + cache_copy(&p->p_fd->fd_nrdir, &nd->nl_rootnch); + if (p->p_fd->fd_njdir.ncp) + cache_copy(&p->p_fd->fd_njdir, &nd->nl_jailnch); nd->nl_cred = crhold(p->p_ucred); } else { - nd->nl_ncp = cache_hold(rootncp); - nd->nl_rootncp = cache_hold(nd->nl_ncp); - nd->nl_jailncp = cache_hold(nd->nl_ncp); + cache_copy(&rootnch, &nd->nl_nch); + cache_copy(&nd->nl_nch, &nd->nl_rootnch); + cache_copy(&nd->nl_nch, &nd->nl_jailnch); nd->nl_cred = crhold(proc0.p_ucred); } nd->nl_td = td; @@ -130,13 +130,13 @@ nlookup_init(struct nlookupdata *nd, /* * This works similarly to nlookup_init() but does not assume a process - * context. rootncp is always chosen for the root directory and the cred + * context. rootnch is always chosen for the root directory and the cred * and starting directory are supplied in arguments. */ int nlookup_init_raw(struct nlookupdata *nd, const char *path, enum uio_seg seg, int flags, - struct ucred *cred, struct namecache *ncstart) + struct ucred *cred, struct nchandle *ncstart) { size_t pathlen; thread_t td; @@ -160,9 +160,9 @@ nlookup_init_raw(struct nlookupdata *nd, error = ENOENT; if (error == 0) { - nd->nl_ncp = cache_hold(ncstart); - nd->nl_rootncp = cache_hold(rootncp); - nd->nl_jailncp = cache_hold(rootncp); + cache_copy(ncstart, &nd->nl_nch); + cache_copy(&rootnch, &nd->nl_rootnch); + cache_copy(&rootnch, &nd->nl_jailnch); nd->nl_cred = crhold(cred); nd->nl_td = td; nd->nl_flags |= flags; @@ -198,22 +198,17 @@ nlookup_set_cred(struct nlookupdata *nd, struct ucred *cred) void nlookup_done(struct nlookupdata *nd) { - if (nd->nl_ncp) { + if (nd->nl_nch.ncp) { if (nd->nl_flags & NLC_NCPISLOCKED) { nd->nl_flags &= ~NLC_NCPISLOCKED; - cache_unlock(nd->nl_ncp); + cache_unlock(&nd->nl_nch); } - cache_drop(nd->nl_ncp); - nd->nl_ncp = NULL; - } - if (nd->nl_rootncp) { - cache_drop(nd->nl_rootncp); - nd->nl_rootncp = NULL; - } - if (nd->nl_jailncp) { - cache_drop(nd->nl_jailncp); - nd->nl_jailncp = NULL; + cache_drop(&nd->nl_nch); } + if (nd->nl_rootnch.ncp) + cache_drop(&nd->nl_rootnch); + if (nd->nl_jailnch.ncp) + cache_drop(&nd->nl_jailnch); if ((nd->nl_flags & NLC_HASBUF) && nd->nl_path) { objcache_put(namei_oc, nd->nl_path); nd->nl_path = NULL; @@ -247,32 +242,32 @@ nlookup_zero(struct nlookupdata *nd) * 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 * +struct nchandle nlookup_simple(const char *str, enum uio_seg seg, int niflags, int *error) { struct nlookupdata nd; - struct namecache *ncp; + struct nchandle nch; *error = nlookup_init(&nd, str, seg, niflags); if (*error == 0) { if ((*error = nlookup(&nd)) == 0) { - ncp = nd.nl_ncp; /* keep hold ref from structure */ - nd.nl_ncp = NULL; /* and NULL out */ + nch = nd.nl_nch; /* keep hold ref from structure */ + cache_zero(&nd.nl_nch); /* and NULL out */ } else { - ncp = NULL; + cache_zero(&nch); } nlookup_done(&nd); } else { - ncp = NULL; + cache_zero(&nch); } - return(ncp); + return(nch); } /* * 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. + * nl_nch 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 @@ -287,7 +282,8 @@ int nlookup(struct nlookupdata *nd) { struct nlcomponent nlc; - struct namecache *ncp; + struct nchandle nch; + struct mount *mp; int wasdotordotdot; char *ptr; char *xptr; @@ -304,17 +300,17 @@ nlookup(struct nlookupdata *nd) * Setup for the loop. The current working namecache element must * be in a refd + unlocked state. This typically the case on entry except * when stringing nlookup()'s along in a chain, since nlookup() always - * returns nl_ncp in a locked state. + * returns nl_nch in a locked state. */ nd->nl_loopcnt = 0; if (nd->nl_flags & NLC_NCPISLOCKED) { nd->nl_flags &= ~NLC_NCPISLOCKED; - cache_unlock(nd->nl_ncp); + cache_unlock(&nd->nl_nch); } ptr = nd->nl_path; /* - * Loop on the path components. At the top of the loop nd->nl_ncp + * Loop on the path components. At the top of the loop nd->nl_nch * is ref'd and unlocked and represents our current position. */ for (;;) { @@ -328,11 +324,11 @@ nlookup(struct nlookupdata *nd) do { ++ptr; } while (*ptr == '/'); - ncp = cache_hold(nd->nl_rootncp); - cache_drop(nd->nl_ncp); - nd->nl_ncp = ncp; + cache_copy(&nd->nl_rootnch, &nch); + cache_drop(&nd->nl_nch); + nd->nl_nch = nch; if (*ptr == 0) { - cache_lock(nd->nl_ncp); + cache_lock(&nd->nl_nch); nd->nl_flags |= NLC_NCPISLOCKED; error = 0; break; @@ -341,9 +337,9 @@ nlookup(struct nlookupdata *nd) } /* - * Check directory search permissions + * Check directory search permissions. */ - if ((error = naccess(nd->nl_ncp, VEXEC, nd->nl_cred)) != 0) + if ((error = naccess(&nd->nl_nch, VEXEC, nd->nl_cred)) != 0) break; /* @@ -360,10 +356,9 @@ nlookup(struct nlookupdata *nd) * 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. + * mount point. If we are at the root, ".." just returns the root. * - * This subsection returns a locked, refd 'ncp' unless it errors out. + * This subsection returns a locked, refd 'nch' unless it errors out. * The namecache topology is not allowed to be disconnected, so * encountering a NULL parent will generate EINVAL. This typically * occurs when a directory is removed out from under a process. @@ -372,46 +367,43 @@ nlookup(struct nlookupdata *nd) * of a path. */ if (nlc.nlc_namelen == 1 && nlc.nlc_nameptr[0] == '.') { - ncp = cache_get(nd->nl_ncp); + cache_get(&nd->nl_nch, &nch); wasdotordotdot = 1; } 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); + if (nd->nl_nch.mount == nd->nl_rootnch.mount && + nd->nl_nch.ncp == nd->nl_rootnch.ncp + ) { + /* + * ".." at the root returns the root + */ + cache_get(&nd->nl_nch, &nch); } else { - while ((ncp->nc_flag & NCF_MOUNTPT) && ncp != nd->nl_rootncp) { - if (ncp->nc_parent->nc_flag & NCF_DESTROYED) - break; - ncp = ncp->nc_parent; /* get to underlying node */ - KKASSERT(ncp != NULL && 1); - } - if (ncp != nd->nl_rootncp) { - if (ncp->nc_parent->nc_flag & NCF_DESTROYED) { - error = EINVAL; - break; - } - ncp = ncp->nc_parent; - if (ncp == NULL) { - error = EINVAL; - break; - } - } - ncp = cache_get(ncp); + /* + * Locate the parent ncp. If we are at the root of a + * filesystem mount we have to skip to the mounted-on + * point in the underlying filesystem. + */ + nch = nd->nl_nch; + while (nch.ncp == nch.mount->mnt_ncmountpt.ncp) + nch = nd->nl_nch.mount->mnt_ncmounton; + nch.ncp = nch.ncp->nc_parent; + KKASSERT(nch.ncp != NULL); + cache_get(&nch, &nch); } wasdotordotdot = 1; } else { - ncp = cache_nlookup(nd->nl_ncp, &nlc); - while ((error = cache_resolve(ncp, nd->nl_cred)) == EAGAIN) { + nch = cache_nlookup(&nd->nl_nch, &nlc); + while ((error = cache_resolve(&nch, nd->nl_cred)) == EAGAIN) { printf("[diagnostic] nlookup: relookup %*.*s\n", - ncp->nc_nlen, ncp->nc_nlen, ncp->nc_name); - cache_put(ncp); - ncp = cache_nlookup(nd->nl_ncp, &nlc); + nch.ncp->nc_nlen, nch.ncp->nc_nlen, nch.ncp->nc_name); + cache_put(&nch); + nch = cache_nlookup(&nd->nl_nch, &nlc); } wasdotordotdot = 0; } /* - * [end of subsection] ncp is locked and ref'd. nd->nl_ncp is ref'd + * [end of subsection] ncp is locked and ref'd. nd->nl_nch is ref'd */ /* @@ -421,11 +413,11 @@ nlookup(struct nlookupdata *nd) * XXX neither '.' nor '..' should return EAGAIN since they were * previously resolved and thus cannot be newly created ncp's. */ - if (ncp->nc_flag & NCF_UNRESOLVED) { - error = cache_resolve(ncp, nd->nl_cred); + if (nch.ncp->nc_flag & NCF_UNRESOLVED) { + error = cache_resolve(&nch, nd->nl_cred); KKASSERT(error != EAGAIN); } else { - error = ncp->nc_error; + error = nch.ncp->nc_error; } /* @@ -441,7 +433,7 @@ nlookup(struct nlookupdata *nd) ; if (*xptr == 0) { if (error == ENOENT && (nd->nl_flags & NLC_CREATE)) - error = naccess(ncp, VCREATE, nd->nl_cred); + error = naccess(&nch, VCREATE, nd->nl_cred); if (error == 0 && wasdotordotdot && (nd->nl_flags & NLC_DELETE)) error = EINVAL; } @@ -450,7 +442,7 @@ nlookup(struct nlookupdata *nd) * Early completion on error. */ if (error) { - cache_put(ncp); + cache_put(&nch); break; } @@ -459,16 +451,16 @@ nlookup(struct nlookupdata *nd) * element or it is the last element and we are allowed to * follow symlinks, resolve the symlink. */ - if ((ncp->nc_flag & NCF_ISSYMLINK) && + if ((nch.ncp->nc_flag & NCF_ISSYMLINK) && (*ptr || (nd->nl_flags & NLC_FOLLOW)) ) { if (nd->nl_loopcnt++ >= MAXSYMLINKS) { error = ELOOP; - cache_put(ncp); + cache_put(&nch); break; } - error = nreadsymlink(nd, ncp, &nlc); - cache_put(ncp); + error = nreadsymlink(nd, &nch, &nlc); + cache_put(&nch); if (error) break; @@ -501,41 +493,30 @@ nlookup(struct nlookupdata *nd) /* * 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 + * Locate the mount. */ - while ((ncp->nc_flag & NCF_ISDIR) && (ncp->nc_flag & NCF_MOUNTEDHERE) - && (nd->nl_flags & NLC_NOCROSSMOUNT) == 0 + while ((nch.ncp->nc_flag & NCF_ISMOUNTPT) && + (nd->nl_flags & NLC_NOCROSSMOUNT) == 0 && + (mp = cache_findmount(&nch)) != NULL ) { - struct mount *mp; struct vnode *tdp; - if ((mp = cache_findmount(ncp)) == NULL) { - printf("warning: nlookup(): ncp marked as a mount point which isn't one at %p %s\n", ncp, ncp->nc_name); - ncp->nc_flag &= ~NCF_MOUNTEDHERE; - break; - } - cache_put(ncp); - ncp = cache_get(mp->mnt_ncp); + cache_put(&nch); + cache_get(&mp->mnt_ncmountpt, &nch); - if (ncp->nc_flag & NCF_UNRESOLVED) { + if (nch.ncp->nc_flag & NCF_UNRESOLVED) { while (vfs_busy(mp, 0)) ; error = VFS_ROOT(mp, &tdp); vfs_unbusy(mp); if (error) break; - cache_setvp(ncp, tdp); + cache_setvp(&nch, tdp); vput(tdp); } } if (error) { - cache_put(ncp); + cache_put(&nch); break; } @@ -547,7 +528,7 @@ nlookup(struct nlookupdata *nd) * to the failure case below. */ while (*ptr == '/') { - if ((ncp->nc_flag & NCF_ISDIR) == 0 && + if ((nch.ncp->nc_flag & NCF_ISDIR) == 0 && !(nd->nl_flags & NLC_WILLBEDIR) ) { break; @@ -559,10 +540,10 @@ nlookup(struct nlookupdata *nd) * Continuation case: additional elements and the current * element is a directory. */ - if (*ptr && (ncp->nc_flag & NCF_ISDIR)) { - cache_drop(nd->nl_ncp); - cache_unlock(ncp); - nd->nl_ncp = ncp; + if (*ptr && (nch.ncp->nc_flag & NCF_ISDIR)) { + cache_drop(&nd->nl_nch); + cache_unlock(&nch); + nd->nl_nch = nch; continue; } @@ -571,7 +552,7 @@ nlookup(struct nlookupdata *nd) * is not a directory */ if (*ptr) { - cache_put(ncp); + cache_put(&nch); error = ENOTDIR; break; } @@ -582,8 +563,8 @@ nlookup(struct nlookupdata *nd) * Check directory permissions if a deletion is specified. */ if (*ptr == 0 && (nd->nl_flags & NLC_DELETE)) { - if ((error = naccess(ncp, VDELETE, nd->nl_cred)) != 0) { - cache_put(ncp); + if ((error = naccess(&nch, VDELETE, nd->nl_cred)) != 0) { + cache_put(&nch); break; } } @@ -593,8 +574,8 @@ nlookup(struct nlookupdata *nd) * ncp may represent a negative hit (ncp->nc_error will be ENOENT), * but we still return an error code of 0. */ - cache_drop(nd->nl_ncp); - nd->nl_ncp = ncp; + cache_drop(&nd->nl_nch); + nd->nl_nch = nch; nd->nl_flags |= NLC_NCPISLOCKED; error = 0; break; @@ -610,29 +591,25 @@ nlookup(struct nlookupdata *nd) * If no error occured a locked, ref'd ncp is stored in *ncpp. */ int -nlookup_mp(struct mount *mp, struct namecache **ncpp) +nlookup_mp(struct mount *mp, struct nchandle *nch) { - struct namecache *ncp; struct vnode *vp; int error; error = 0; - ncp = mp->mnt_ncp; - cache_get(ncp); - if (ncp->nc_flag & NCF_UNRESOLVED) { + cache_get(&mp->mnt_ncmountpt, nch); + if (nch->ncp->nc_flag & NCF_UNRESOLVED) { while (vfs_busy(mp, 0)) ; error = VFS_ROOT(mp, &vp); vfs_unbusy(mp); if (error) { - cache_put(ncp); - ncp = NULL; + cache_put(nch); } else { - cache_setvp(ncp, vp); + cache_setvp(nch, vp); vput(vp); } } - *ncpp = ncp; return(error); } @@ -643,7 +620,7 @@ nlookup_mp(struct mount *mp, struct namecache **ncpp) * If an error occurs no buffer will be allocated or returned in the nlc. */ int -nreadsymlink(struct nlookupdata *nd, struct namecache *ncp, +nreadsymlink(struct nlookupdata *nd, struct nchandle *nch, struct nlcomponent *nlc) { struct vnode *vp; @@ -655,9 +632,9 @@ nreadsymlink(struct nlookupdata *nd, struct namecache *ncp, nlc->nlc_nameptr = NULL; nlc->nlc_namelen = 0; - if (ncp->nc_vp == NULL) + if (nch->ncp->nc_vp == NULL) return(ENOENT); - if ((error = cache_vget(ncp, nd->nl_cred, LK_SHARED, &vp)) != 0) + if ((error = cache_vget(nch, nd->nl_cred, LK_SHARED, &vp)) != 0) return(error); cp = objcache_get(namei_oc, M_WAITOK); aiov.iov_base = cp; @@ -711,37 +688,38 @@ fail: * checks. */ int -naccess(struct namecache *ncp, int vmode, struct ucred *cred) +naccess(struct nchandle *nch, int vmode, struct ucred *cred) { - struct namecache *par; + struct nchandle par; struct vnode *vp; struct vattr va; int error; - if (ncp->nc_flag & NCF_UNRESOLVED) { - cache_lock(ncp); - cache_resolve(ncp, cred); - cache_unlock(ncp); + if (nch->ncp->nc_flag & NCF_UNRESOLVED) { + cache_lock(nch); + cache_resolve(nch, cred); + cache_unlock(nch); } - error = ncp->nc_error; + error = nch->ncp->nc_error; if (vmode & (VDELETE|VCREATE|VEXCL)) { - if (((vmode & VCREATE) && ncp->nc_vp == NULL) || - ((vmode & VDELETE) && ncp->nc_vp != NULL) + if (((vmode & VCREATE) && nch->ncp->nc_vp == NULL) || + ((vmode & VDELETE) && nch->ncp->nc_vp != NULL) ) { - if ((par = ncp->nc_parent) == NULL) { + if ((par.ncp = nch->ncp->nc_parent) == NULL) { if (error != EAGAIN) error = EINVAL; } else { - cache_hold(par); - error = naccess(par, VWRITE, cred); - cache_drop(par); + par.mount = nch->mount; + cache_hold(&par); + error = naccess(&par, VWRITE, cred); + cache_drop(&par); } } - if ((vmode & VEXCL) && ncp->nc_vp != NULL) + if ((vmode & VEXCL) && nch->ncp->nc_vp != NULL) error = EEXIST; } if (error == 0) { - error = cache_vget(ncp, cred, LK_SHARED, &vp); + error = cache_vget(nch, cred, LK_SHARED, &vp); if (error == ENOENT) { if (vmode & VCREATE) error = 0; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 6b7a56475c..f13a0fb7c8 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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.106 2006/09/19 18:17:46 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.107 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -65,19 +65,22 @@ #include #include #include - -#include -#include #include +#include +#include + #include #include #include -#include -#include +#include +#include + +#include +static void mount_warning(struct mount *mp, const char *ctl, ...); static int checkvp_chdir (struct vnode *vn, struct thread *td); -static void checkdirs (struct vnode *olddp, struct namecache *ncp); +static void checkdirs (struct vnode *olddp, struct nchandle *nch); static int chroot_refuse_vdir_fds (struct filedesc *fdp); static int chroot_visible_mnt(struct mount *mp, struct proc *p); static int getutimes (const struct timeval *, struct timespec *); @@ -108,7 +111,7 @@ sys_mount(struct mount_args *uap) struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; - struct namecache *ncp; + struct nchandle nch; struct mount *mp; struct vfsconf *vfsp; int error, flag = 0, flag2 = 0; @@ -116,7 +119,6 @@ sys_mount(struct mount_args *uap) struct vattr va; struct nlookupdata nd; char fstypename[MFSNAMELEN]; - struct nlcomponent nlc; struct ucred *cred = p->p_ucred; KKASSERT(p); @@ -139,12 +141,12 @@ sys_mount(struct mount_args *uap) uap->flags |= MNT_NOSUID | MNT_NODEV; /* - * Lookup the requested path and extract the ncp and vnode. + * Lookup the requested path and extract the nch and vnode. */ 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) + if (nd.nl_nch.ncp->nc_vp == NULL) error = ENOENT; } } @@ -156,32 +158,32 @@ sys_mount(struct mount_args *uap) /* * Extract the locked+refd ncp and cleanup the nd structure */ - ncp = nd.nl_ncp; - nd.nl_ncp = NULL; + nch = nd.nl_nch; + cache_zero(&nd.nl_nch); nlookup_done(&nd); - if ((ncp->nc_flag & NCF_MOUNTEDHERE) && cache_findmount(ncp)) + if ((nch.ncp->nc_flag & NCF_ISMOUNTPT) && cache_findmount(&nch)) hasmount = 1; else hasmount = 0; /* - * now we have the locked ref'd ncp and unreferenced vnode. + * now we have the locked ref'd nch and unreferenced vnode. */ - vp = ncp->nc_vp; + vp = nch.ncp->nc_vp; if ((error = vget(vp, LK_EXCLUSIVE)) != 0) { - cache_put(ncp); + cache_put(&nch); return (error); } - cache_unlock(ncp); + cache_unlock(&nch); /* - * Now we have an unlocked ref'd ncp and a locked ref'd vp + * Now we have an unlocked ref'd nch and a locked ref'd vp */ if (uap->flags & MNT_UPDATE) { if ((vp->v_flag & VROOT) == 0) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (EINVAL); } @@ -194,7 +196,7 @@ sys_mount(struct mount_args *uap) */ if ((uap->flags & MNT_RELOAD) && ((mp->mnt_flag & MNT_RDONLY) == 0)) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (EOPNOTSUPP); /* Needs translation */ } @@ -204,17 +206,17 @@ sys_mount(struct mount_args *uap) */ if (mp->mnt_stat.f_owner != cred->cr_uid && (error = suser(td))) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (error); } if (vfs_busy(mp, LK_NOWAIT)) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (EBUSY); } if ((vp->v_flag & VMOUNT) != 0 || hasmount) { - cache_drop(ncp); + cache_drop(&nch); vfs_unbusy(mp); vput(vp); return (EBUSY); @@ -231,22 +233,22 @@ sys_mount(struct mount_args *uap) */ if ((error = VOP_GETATTR(vp, &va)) || (va.va_uid != cred->cr_uid && (error = suser(td)))) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (error); } if ((error = vinvalbuf(vp, V_SAVE, 0, 0)) != 0) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (error); } if (vp->v_type != VDIR) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (ENOTDIR); } if ((error = copyinstr(uap->type, fstypename, MFSNAMELEN, NULL)) != 0) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (error); } @@ -259,13 +261,13 @@ sys_mount(struct mount_args *uap) /* Only load modules for root (very important!) */ if ((error = suser(td)) != 0) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return error; } error = linker_load_file(fstypename, &lf); if (error || lf == NULL) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); if (lf == NULL) error = ENODEV; @@ -280,13 +282,13 @@ sys_mount(struct mount_args *uap) if (vfsp == NULL) { lf->userrefs--; linker_file_unload(lf); - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (ENODEV); } } if ((vp->v_flag & VMOUNT) != 0 || hasmount) { - cache_drop(ncp); + cache_drop(&nch); vput(vp); return (EBUSY); } @@ -345,33 +347,36 @@ update: vfs_unbusy(mp); vp->v_flag &= ~VMOUNT; vrele(vp); - cache_drop(ncp); + cache_drop(&nch); return (error); } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* * 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. + * point gets its own mnt_ncmountpt (unless the VFS already set one + * up) which represents the root of the mount. The lookup code + * detects the mount point going forward and checks the root of + * the mount going backwards. * * It is not necessary to invalidate or purge the vnode underneath * because elements under the mount will be given their own glue * namecache record. */ if (!error) { - nlc.nlc_nameptr = ""; - nlc.nlc_namelen = 0; - mp->mnt_ncp = cache_nlookup(ncp, &nlc); - cache_setunresolved(mp->mnt_ncp); - cache_setmountpt(mp->mnt_ncp, mp); - cache_drop(ncp); - /* XXX get the root of the fs and cache_setvp(mnt_ncp...) */ + if (mp->mnt_ncmountpt.ncp == NULL) { + /* + * allocate, then unlock, but leave the ref intact + */ + cache_allocroot(&mp->mnt_ncmountpt, mp, NULL); + cache_unlock(&mp->mnt_ncmountpt); + } + mp->mnt_ncmounton = nch; /* inherits ref */ + nch.ncp->nc_flag |= NCF_ISMOUNTPT; + + /* XXX get the root of the fs and cache_setvp(mnt_ncmountpt...) */ vp->v_flag &= ~VMOUNT; mountlist_insert(mp, MNTINS_LAST); - checkdirs(vp, mp->mnt_ncp); - cache_unlock(mp->mnt_ncp); /* leave ref intact */ + checkdirs(vp, &mp->mnt_ncmounton); vn_unlock(vp); error = vfs_allocate_syncvnode(mp); vfs_unbusy(mp); @@ -387,7 +392,7 @@ update: mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); kfree(mp, M_MOUNT); - cache_drop(ncp); + cache_drop(&nch); vput(vp); } return (error); @@ -405,13 +410,13 @@ update: struct checkdirs_info { struct vnode *olddp; struct vnode *newdp; - struct namecache *ncp; + struct nchandle nch; }; static int checkdirs_callback(struct proc *p, void *data); static void -checkdirs(struct vnode *olddp, struct namecache *ncp) +checkdirs(struct vnode *olddp, struct nchandle *nch) { struct checkdirs_info info; struct vnode *newdp; @@ -419,19 +424,19 @@ checkdirs(struct vnode *olddp, struct namecache *ncp) if (olddp->v_usecount == 1) return; - mp = ncp->nc_mount; + mp = nch->mount; if (VFS_ROOT(mp, &newdp)) panic("mount: lost mount"); - cache_setvp(ncp, newdp); + cache_setvp(nch, newdp); if (rootvnode == olddp) { vref(newdp); - vfs_cache_setroot(newdp, cache_hold(ncp)); + vfs_cache_setroot(newdp, cache_hold(nch)); } info.olddp = olddp; info.newdp = newdp; - info.ncp = ncp; + info.nch = *nch; allproc_scan(checkdirs_callback, &info); vput(newdp); } @@ -445,14 +450,14 @@ checkdirs_callback(struct proc *p, void *data) { struct checkdirs_info *info = data; struct filedesc *fdp; - struct namecache *ncdrop1; - struct namecache *ncdrop2; + struct nchandle ncdrop1; + struct nchandle ncdrop2; struct vnode *vprele1; struct vnode *vprele2; if ((fdp = p->p_fd) != NULL) { - ncdrop1 = NULL; - ncdrop2 = NULL; + cache_zero(&ncdrop1); + cache_zero(&ncdrop2); vprele1 = NULL; vprele2 = NULL; @@ -469,20 +474,20 @@ checkdirs_callback(struct proc *p, void *data) vref(info->newdp); fdp->fd_cdir = info->newdp; ncdrop1 = fdp->fd_ncdir; - fdp->fd_ncdir = cache_hold(info->ncp); + cache_copy(&info->nch, &fdp->fd_ncdir); } if (fdp->fd_rdir == info->olddp) { vprele2 = fdp->fd_rdir; vref(info->newdp); fdp->fd_rdir = info->newdp; ncdrop2 = fdp->fd_nrdir; - fdp->fd_nrdir = cache_hold(info->ncp); + cache_copy(&info->nch, &fdp->fd_nrdir); } spin_unlock_wr(&fdp->fd_spin); - if (ncdrop1) - cache_drop(ncdrop1); - if (ncdrop2) - cache_drop(ncdrop2); + if (ncdrop1.ncp) + cache_drop(&ncdrop1); + if (ncdrop2.ncp) + cache_drop(&ncdrop2); if (vprele1) vrele(vprele1); if (vprele2) @@ -522,7 +527,7 @@ sys_unmount(struct unmount_args *uap) if (error) goto out; - mp = nd.nl_ncp->nc_mount; + mp = nd.nl_nch.mount; /* * Only root, or the user that did the original mount is @@ -543,7 +548,7 @@ sys_unmount(struct unmount_args *uap) /* * Must be the root of the filesystem */ - if (!(nd.nl_ncp->nc_flag & NCF_MOUNTPT)) { + if (nd.nl_nch.ncp != mp->mnt_ncmountpt.ncp) { error = EINVAL; goto out; } @@ -571,9 +576,11 @@ int dounmount(struct mount *mp, int flags) { struct namecache *ncp; + struct nchandle nch; int error; int async_flag; int lflags; + int freeok = 1; /* * Exclusive access for unmounting purposes @@ -603,33 +610,54 @@ dounmount(struct mount *mp, int flags) mp->mnt_flag &=~ MNT_ASYNC; /* - * remove cache entries for this file sys and determine if anyone - * other then us is still holding onto any namecache references. - * - * XXX need separate ref counter on mount structure to delay - * kfree()ing it. + * If this filesystem isn't aliasing other filesystems, + * try to invalidate any remaining namecache entries and + * check the count afterwords. */ - cache_purgevfs(mp); - if ((ncp = mp->mnt_ncp) != NULL) { - if (ncp->nc_refs != 1 || TAILQ_FIRST(&ncp->nc_list)) { - char *ptr; - char *buf; + if ((mp->mnt_kern_flag & MNTK_NCALIASED) == 0) { + cache_lock(&mp->mnt_ncmountpt); + cache_inval(&mp->mnt_ncmountpt, CINV_DESTROY|CINV_CHILDREN); + cache_unlock(&mp->mnt_ncmountpt); + + if ((ncp = mp->mnt_ncmountpt.ncp) != NULL && + (ncp->nc_refs != 1 || TAILQ_FIRST(&ncp->nc_list))) { if ((flags & MNT_FORCE) == 0) { error = EBUSY; - } else if (cache_fullpath(NULL, ncp, &ptr, &buf)) { - printf("Warning: forced unmount - " - "namecache references still present\n"); + mount_warning(mp, "Cannot unmount: " + "%d namecache " + "references still " + "present", + ncp->nc_refs - 1); } else { - printf("Warning: forced unmount of %s - " - "namecache references still present\n", - ptr - ); - kfree(buf, M_TEMP); + mount_warning(mp, "Forced unmount: " + "%d namecache " + "references still " + "present", + ncp->nc_refs - 1); + freeok = 0; } } } + /* + * nchandle records ref the mount structure. Expect a count of 1 + * (our mount->mnt_ncmountpt). + */ + if (mp->mnt_refs != 1) { + if ((flags & MNT_FORCE) == 0) { + mount_warning(mp, "Cannot unmount: " + "%d process references still " + "present", mp->mnt_refs); + error = EBUSY; + } else { + mount_warning(mp, "Forced unmount: " + "%d process references still " + "present", mp->mnt_refs); + freeok = 0; + } + } + if (error == 0) { if (mp->mnt_syncer != NULL) vrele(mp->mnt_syncer); @@ -668,10 +696,17 @@ dounmount(struct mount *mp, int flags) vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_spec_ops); vfs_rm_vnodeops(mp, NULL, &mp->mnt_vn_fifo_ops); - if ((ncp = mp->mnt_ncp) != NULL) { - cache_clrmountpt(ncp); - cache_drop(ncp); - mp->mnt_ncp = NULL; + if (mp->mnt_ncmountpt.ncp != NULL) { + nch = mp->mnt_ncmountpt; + cache_zero(&mp->mnt_ncmountpt); + cache_clrmountpt(&nch); + cache_drop(&nch); + } + if (mp->mnt_ncmounton.ncp != NULL) { + nch = mp->mnt_ncmounton; + cache_zero(&mp->mnt_ncmounton); + cache_clrmountpt(&nch); + cache_drop(&nch); } mp->mnt_vfc->vfc_refcount--; @@ -680,10 +715,33 @@ dounmount(struct mount *mp, int flags) lockmgr(&mp->mnt_lock, LK_RELEASE); if (mp->mnt_kern_flag & MNTK_MWAIT) wakeup(mp); - kfree(mp, M_MOUNT); + if (freeok) + kfree(mp, M_MOUNT); return (0); } +static +void +mount_warning(struct mount *mp, const char *ctl, ...) +{ + char *ptr; + char *buf; + __va_list va; + + __va_start(va, ctl); + if (cache_fullpath(NULL, &mp->mnt_ncmounton, &ptr, &buf) == 0) { + printf("unmount(%s): ", ptr); + vprintf(ctl, va); + printf("\n"); + kfree(buf, M_TEMP); + } else { + printf("unmount(%p): ", mp); + vprintf(ctl, va); + printf("\n"); + } + __va_end(va); +} + /* * Sync each mounted filesystem. */ @@ -756,7 +814,7 @@ sys_quotactl(struct quotactl_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) { - mp = nd.nl_ncp->nc_mount; + mp = nd.nl_nch.mount; error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, nd.nl_cred); } @@ -869,7 +927,7 @@ kern_mountctl(const char *path, int op, struct file *fp, if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error) return (error); @@ -901,12 +959,12 @@ kern_statfs(struct nlookupdata *nd, struct statfs *buf) if ((error = nlookup(nd)) != 0) return (error); - mp = nd->nl_ncp->nc_mount; + mp = nd->nl_nch.mount; sp = &mp->mnt_stat; if ((error = VFS_STATFS(mp, sp, nd->nl_cred)) != 0) return (error); - error = cache_fullpath(p, mp->mnt_ncp, &fullpath, &freepath); + error = cache_fullpath(p, &mp->mnt_ncmountpt, &fullpath, &freepath); if (error) return(error); bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); @@ -969,7 +1027,7 @@ kern_fstatfs(int fd, struct statfs *buf) if ((error = VFS_STATFS(mp, sp, fp->f_cred)) != 0) goto done; - if ((error = cache_fullpath(p, mp->mnt_ncp, &fullpath, &freepath)) != 0) + if ((error = cache_fullpath(p, &mp->mnt_ncmountpt, &fullpath, &freepath)) != 0) goto done; bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); strlcpy(sp->f_mntonname, fullpath, sizeof(sp->f_mntonname)); @@ -1017,7 +1075,6 @@ struct getfsstat_info { long maxcount; int error; int flags; - int is_chrooted; struct proc *p; }; @@ -1032,10 +1089,6 @@ sys_getfsstat(struct getfsstat_args *uap) struct getfsstat_info info; bzero(&info, sizeof(info)); - if (p != NULL && (p->p_fd->fd_nrdir->nc_flag & NCF_ROOT) == 0) - info.is_chrooted = 1; - else - info.is_chrooted = 0; info.maxcount = uap->bufsize / sizeof(struct statfs); info.sfsp = uap->buf; @@ -1061,7 +1114,7 @@ getfsstat_callback(struct mount *mp, void *data) int error; if (info->sfsp && info->count < info->maxcount) { - if (info->is_chrooted && !chroot_visible_mnt(mp, info->p)) + if (info->p && !chroot_visible_mnt(mp, info->p)) return(0); sp = &mp->mnt_stat; @@ -1077,7 +1130,7 @@ getfsstat_callback(struct mount *mp, void *data) } sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - error = cache_fullpath(info->p, mp->mnt_ncp, + error = cache_fullpath(info->p, &mp->mnt_ncmountpt, &fullpath, &freepath); if (error) { info->error = error; @@ -1113,8 +1166,7 @@ sys_fchdir(struct fchdir_args *uap) struct vnode *vp, *ovp; struct mount *mp; struct file *fp; - struct namecache *ncp, *oncp; - struct namecache *nct; + struct nchandle nch, onch, tnch; int error; if ((error = holdvnode(fdp, uap->fd, &fp)) != 0) @@ -1122,7 +1174,7 @@ sys_fchdir(struct fchdir_args *uap) vp = (struct vnode *)fp->f_data; vref(vp); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - if (vp->v_type != VDIR || fp->f_ncp == NULL) + if (vp->v_type != VDIR || fp->f_nchandle.ncp == NULL) error = ENOTDIR; else error = VOP_ACCESS(vp, VEXEC, p->p_ucred); @@ -1131,37 +1183,37 @@ sys_fchdir(struct fchdir_args *uap) fdrop(fp); return (error); } - ncp = cache_hold(fp->f_ncp); + cache_copy(&fp->f_nchandle, &nch); /* * If the ncp has become a mount point, traverse through * the mount point. */ - while (!error && (ncp->nc_flag & NCF_MOUNTEDHERE) && - (mp = cache_findmount(ncp)) != NULL + while (!error && (nch.ncp->nc_flag & NCF_ISMOUNTPT) && + (mp = cache_findmount(&nch)) != NULL ) { - error = nlookup_mp(mp, &nct); + error = nlookup_mp(mp, &tnch); if (error == 0) { - cache_unlock(nct); /* leave ref intact */ + cache_unlock(&tnch); /* leave ref intact */ vput(vp); - vp = nct->nc_vp; + vp = tnch.ncp->nc_vp; error = vget(vp, LK_SHARED); KKASSERT(error == 0); - cache_drop(ncp); - ncp = nct; + cache_drop(&nch); + nch = tnch; } } if (error == 0) { ovp = fdp->fd_cdir; - oncp = fdp->fd_ncdir; + onch = fdp->fd_ncdir; vn_unlock(vp); /* leave ref intact */ fdp->fd_cdir = vp; - fdp->fd_ncdir = ncp; - cache_drop(oncp); + fdp->fd_ncdir = nch; + cache_drop(&onch); vrele(ovp); } else { - cache_drop(ncp); + cache_drop(&nch); vput(vp); } fdrop(fp); @@ -1175,12 +1227,12 @@ kern_chdir(struct nlookupdata *nd) struct proc *p = td->td_proc; struct filedesc *fdp = p->p_fd; struct vnode *vp, *ovp; - struct namecache *oncp; + struct nchandle onch; int error; if ((error = nlookup(nd)) != 0) return (error); - if ((vp = nd->nl_ncp->nc_vp) == NULL) + if ((vp = nd->nl_nch.ncp->nc_vp) == NULL) return (ENOENT); if ((error = vget(vp, LK_SHARED)) != 0) return (error); @@ -1189,13 +1241,13 @@ kern_chdir(struct nlookupdata *nd) vn_unlock(vp); 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; + onch = fdp->fd_ncdir; + cache_unlock(&nd->nl_nch); /* leave reference intact */ + fdp->fd_ncdir = nd->nl_nch; fdp->fd_cdir = vp; - cache_drop(oncp); + cache_drop(&onch); vrele(ovp); - nd->nl_ncp = NULL; + cache_zero(&nd->nl_nch); } else { vrele(vp); } @@ -1266,7 +1318,7 @@ SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, * remain locked and referenced on return. */ int -kern_chroot(struct namecache *ncp) +kern_chroot(struct nchandle *nch) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -1288,7 +1340,7 @@ kern_chroot(struct namecache *ncp) if ((error = chroot_refuse_vdir_fds(fdp)) != 0) return (error); } - if ((vp = ncp->nc_vp) == NULL) + if ((vp = nch->ncp->nc_vp) == NULL) return (ENOENT); if ((error = vget(vp, LK_SHARED)) != 0) @@ -1303,12 +1355,12 @@ kern_chroot(struct namecache *ncp) if (error == 0) { vrele(fdp->fd_rdir); fdp->fd_rdir = vp; /* reference inherited by fd_rdir */ - cache_drop(fdp->fd_nrdir); - fdp->fd_nrdir = cache_hold(ncp); + cache_drop(&fdp->fd_nrdir); + cache_copy(nch, &fdp->fd_nrdir); if (fdp->fd_jdir == NULL) { fdp->fd_jdir = vp; vref(fdp->fd_jdir); - fdp->fd_njdir = cache_hold(ncp); + cache_copy(nch, &fdp->fd_njdir); } } else { vrele(vp); @@ -1337,7 +1389,7 @@ sys_chroot(struct chroot_args *uap) } error = nlookup(&nd); if (error == 0) - error = kern_chroot(nd.nl_ncp); + error = kern_chroot(&nd.nl_nch); nlookup_done(&nd); return(error); } @@ -1516,7 +1568,6 @@ sys_open(struct open_args *uap) int kern_mknod(struct nlookupdata *nd, int mode, int dev) { - struct namecache *ncp; struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; @@ -1542,10 +1593,9 @@ kern_mknod(struct nlookupdata *nd, int mode, int dev) nd->nl_flags |= NLC_CREATE; if ((error = nlookup(nd)) != 0) return (error); - ncp = nd->nl_ncp; - if (ncp->nc_vp) + if (nd->nl_nch.ncp->nc_vp) return (EEXIST); - if ((error = ncp_writechk(ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(&vattr); @@ -1572,10 +1622,10 @@ kern_mknod(struct nlookupdata *nd, int mode, int dev) } if (error == 0) { if (whiteout) { - error = VOP_NWHITEOUT(ncp, nd->nl_cred, NAMEI_CREATE); + error = VOP_NWHITEOUT(&nd->nl_nch, nd->nl_cred, NAMEI_CREATE); } else { vp = NULL; - error = VOP_NMKNOD(ncp, &vp, nd->nl_cred, &vattr); + error = VOP_NMKNOD(&nd->nl_nch, &vp, nd->nl_cred, &vattr); if (error == 0) vput(vp); } @@ -1604,7 +1654,6 @@ sys_mknod(struct mknod_args *uap) int kern_mkfifo(struct nlookupdata *nd, int mode) { - struct namecache *ncp; struct thread *td = curthread; struct proc *p = td->td_proc; struct vattr vattr; @@ -1616,17 +1665,16 @@ kern_mkfifo(struct nlookupdata *nd, int mode) nd->nl_flags |= NLC_CREATE; if ((error = nlookup(nd)) != 0) return (error); - ncp = nd->nl_ncp; - if (ncp->nc_vp) + if (nd->nl_nch.ncp->nc_vp) return (EEXIST); - if ((error = ncp_writechk(ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(&vattr); vattr.va_type = VFIFO; vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask; vp = NULL; - error = VOP_NMKNOD(ncp, &vp, nd->nl_cred, &vattr); + error = VOP_NMKNOD(&nd->nl_nch, &vp, nd->nl_cred, &vattr); if (error == 0) vput(vp); return (error); @@ -1716,11 +1764,11 @@ kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) bwillwrite(); if ((error = nlookup(nd)) != 0) return (error); - vp = nd->nl_ncp->nc_vp; + vp = nd->nl_nch.ncp->nc_vp; KKASSERT(vp != NULL); if (vp->v_type == VDIR) return (EPERM); /* POSIX */ - if ((error = ncp_writechk(nd->nl_ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); if ((error = vget(vp, LK_EXCLUSIVE)) != 0) return (error); @@ -1732,14 +1780,14 @@ kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) */ KKASSERT(nd->nl_flags & NLC_NCPISLOCKED); nd->nl_flags &= ~NLC_NCPISLOCKED; - cache_unlock(nd->nl_ncp); + cache_unlock(&nd->nl_nch); linknd->nl_flags |= NLC_CREATE; if ((error = nlookup(linknd)) != 0) { vput(vp); return (error); } - if (linknd->nl_ncp->nc_vp) { + if (linknd->nl_nch.ncp->nc_vp) { vput(vp); return (EEXIST); } @@ -1749,7 +1797,7 @@ kern_link(struct nlookupdata *nd, struct nlookupdata *linknd) */ error = can_hardlink(vp, td, td->td_proc->p_ucred); if (error == 0) - error = VOP_NLINK(linknd->nl_ncp, vp, linknd->nl_cred); + error = VOP_NLINK(&linknd->nl_nch, vp, linknd->nl_cred); vput(vp); return (error); } @@ -1779,7 +1827,6 @@ sys_link(struct link_args *uap) int kern_symlink(struct nlookupdata *nd, char *path, int mode) { - struct namecache *ncp; struct vattr vattr; struct vnode *vp; int error; @@ -1788,14 +1835,13 @@ kern_symlink(struct nlookupdata *nd, char *path, int mode) nd->nl_flags |= NLC_CREATE; if ((error = nlookup(nd)) != 0) return (error); - ncp = nd->nl_ncp; - if (ncp->nc_vp) + if (nd->nl_nch.ncp->nc_vp) return (EEXIST); - if ((error = ncp_writechk(ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(&vattr); vattr.va_mode = mode; - error = VOP_NSYMLINK(ncp, &vp, nd->nl_cred, &vattr, path); + error = VOP_NSYMLINK(&nd->nl_nch, &vp, nd->nl_cred, &vattr, path); if (error == 0) vput(vp); return (error); @@ -1847,9 +1893,9 @@ sys_undelete(struct undelete_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = ncp_writechk(nd.nl_ncp); + error = ncp_writechk(&nd.nl_nch); if (error == 0) - error = VOP_NWHITEOUT(nd.nl_ncp, nd.nl_cred, NAMEI_DELETE); + error = VOP_NWHITEOUT(&nd.nl_nch, nd.nl_cred, NAMEI_DELETE); nlookup_done(&nd); return (error); } @@ -1857,17 +1903,15 @@ sys_undelete(struct undelete_args *uap) int kern_unlink(struct nlookupdata *nd) { - struct namecache *ncp; int error; bwillwrite(); nd->nl_flags |= NLC_DELETE; if ((error = nlookup(nd)) != 0) return (error); - ncp = nd->nl_ncp; - if ((error = ncp_writechk(ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); - error = VOP_NREMOVE(ncp, nd->nl_cred); + error = VOP_NREMOVE(&nd->nl_nch, nd->nl_cred); return (error); } @@ -1955,7 +1999,7 @@ kern_access(struct nlookupdata *nd, int aflags) if ((error = nlookup(nd)) != 0) return (error); retry: - error = cache_vget(nd->nl_ncp, nd->nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, &vp); if (error) return (error); @@ -1969,7 +2013,7 @@ retry: if (aflags & X_OK) flags |= VEXEC; if ((flags & VWRITE) == 0 || - (error = vn_writechk(vp, nd->nl_ncp)) == 0) + (error = vn_writechk(vp, &nd->nl_nch)) == 0) error = VOP_ACCESS(vp, flags, nd->nl_cred); /* @@ -1977,8 +2021,8 @@ retry: * entry. This is a hack at the moment. */ if (error == ESTALE) { - cache_setunresolved(nd->nl_ncp); - error = cache_resolve(nd->nl_ncp, nd->nl_cred); + cache_setunresolved(&nd->nl_nch); + error = cache_resolve(&nd->nl_nch, nd->nl_cred); if (error == 0) { vput(vp); vp = NULL; @@ -2018,7 +2062,7 @@ kern_stat(struct nlookupdata *nd, struct stat *st) if ((error = nlookup(nd)) != 0) return (error); again: - if ((vp = nd->nl_ncp->nc_vp) == NULL) + if ((vp = nd->nl_nch.ncp->nc_vp) == NULL) return (ENOENT); td = curthread; @@ -2031,8 +2075,8 @@ again: * is a hack at the moment. */ if (error == ESTALE) { - cache_setunresolved(nd->nl_ncp); - error = cache_resolve(nd->nl_ncp, nd->nl_cred); + cache_setunresolved(&nd->nl_nch); + error = cache_resolve(&nd->nl_nch, nd->nl_cred); if (error == 0) { vput(vp); goto again; @@ -2104,7 +2148,7 @@ sys_pathconf(struct pathconf_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error == 0) { error = VOP_PATHCONF(vp, uap->name, uap->sysmsg_fds); @@ -2130,7 +2174,7 @@ kern_readlink(struct nlookupdata *nd, char *buf, int count, int *res) if ((error = nlookup(nd)) != 0) return (error); - error = cache_vget(nd->nl_ncp, nd->nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, &vp); if (error) return (error); if (vp->v_type != VLNK) { @@ -2222,9 +2266,9 @@ sys_chflags(struct chflags_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = ncp_writechk(nd.nl_ncp); + error = ncp_writechk(&nd.nl_nch); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error == 0) { error = setfflags(vp, uap->flags); @@ -2249,8 +2293,8 @@ sys_fchflags(struct fchflags_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); - if (fp->f_ncp) - error = ncp_writechk(fp->f_ncp); + if (fp->f_nchandle.ncp) + error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfflags((struct vnode *) fp->f_data, uap->flags); fdrop(fp); @@ -2287,9 +2331,9 @@ kern_chmod(struct nlookupdata *nd, int mode) /* XXX Add NLC flag indicating modifying operation? */ if ((error = nlookup(nd)) != 0) return (error); - if ((error = cache_vref(nd->nl_ncp, nd->nl_cred, &vp)) != 0) + if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) return (error); - if ((error = ncp_writechk(nd->nl_ncp)) == 0) + if ((error = ncp_writechk(&nd->nl_nch)) == 0) error = setfmode(vp, mode); vrele(vp); return (error); @@ -2349,8 +2393,8 @@ sys_fchmod(struct fchmod_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); - if (fp->f_ncp) - error = ncp_writechk(fp->f_ncp); + if (fp->f_nchandle.ncp) + error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfmode((struct vnode *)fp->f_data, uap->mode); fdrop(fp); @@ -2388,9 +2432,9 @@ kern_chown(struct nlookupdata *nd, int uid, int gid) /* XXX Add NLC flag indicating modifying operation? */ if ((error = nlookup(nd)) != 0) return (error); - if ((error = cache_vref(nd->nl_ncp, nd->nl_cred, &vp)) != 0) + if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) return (error); - if ((error = ncp_writechk(nd->nl_ncp)) == 0) + if ((error = ncp_writechk(&nd->nl_nch)) == 0) error = setfown(vp, uid, gid); vrele(vp); return (error); @@ -2448,8 +2492,8 @@ sys_fchown(struct fchown_args *uap) if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0) return (error); - if (fp->f_ncp) - error = ncp_writechk(fp->f_ncp); + if (fp->f_nchandle.ncp) + error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setfown((struct vnode *)fp->f_data, uap->uid, uap->gid); fdrop(fp); @@ -2508,9 +2552,9 @@ kern_utimes(struct nlookupdata *nd, struct timeval *tptr) /* XXX Add NLC flag indicating modifying operation? */ if ((error = nlookup(nd)) != 0) return (error); - if ((error = ncp_writechk(nd->nl_ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); - if ((error = cache_vref(nd->nl_ncp, nd->nl_cred, &vp)) != 0) + if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) return (error); error = setutimes(vp, ts, tptr == NULL); vrele(vp); @@ -2579,8 +2623,8 @@ kern_futimes(int fd, struct timeval *tptr) return (error); if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) return (error); - if (fp->f_ncp) - error = ncp_writechk(fp->f_ncp); + if (fp->f_nchandle.ncp) + error = ncp_writechk(&fp->f_nchandle); if (error == 0) error = setutimes((struct vnode *)fp->f_data, ts, tptr == NULL); fdrop(fp); @@ -2621,9 +2665,9 @@ kern_truncate(struct nlookupdata *nd, off_t length) /* XXX Add NLC flag indicating modifying operation? */ if ((error = nlookup(nd)) != 0) return (error); - if ((error = ncp_writechk(nd->nl_ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); - if ((error = cache_vref(nd->nl_ncp, nd->nl_cred, &vp)) != 0) + if ((error = cache_vref(&nd->nl_nch, nd->nl_cred, &vp)) != 0) return (error); if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0) { vrele(vp); @@ -2631,7 +2675,7 @@ kern_truncate(struct nlookupdata *nd, off_t length) } if (vp->v_type == VDIR) { error = EISDIR; - } else if ((error = vn_writechk(vp, nd->nl_ncp)) == 0 && + } else if ((error = vn_writechk(vp, &nd->nl_nch)) == 0 && (error = VOP_ACCESS(vp, VWRITE, nd->nl_cred)) == 0) { VATTR_NULL(&vattr); vattr.va_size = length; @@ -2673,8 +2717,8 @@ kern_ftruncate(int fd, off_t length) return(EINVAL); if ((error = holdvnode(p->p_fd, fd, &fp)) != 0) return (error); - if (fp->f_ncp) { - error = ncp_writechk(fp->f_ncp); + if (fp->f_nchandle.ncp) { + error = ncp_writechk(&fp->f_nchandle); if (error) goto done; } @@ -2747,8 +2791,8 @@ sys_fsync(struct fsync_args *uap) int kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) { - struct namecache *fncpd; - struct namecache *tncpd; + struct nchandle fnchd; + struct nchandle tnchd; struct namecache *ncp; struct mount *mp; int error; @@ -2756,12 +2800,13 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) bwillwrite(); if ((error = nlookup(fromnd)) != 0) return (error); - if ((fncpd = fromnd->nl_ncp->nc_parent) == NULL) + if ((fnchd.ncp = fromnd->nl_nch.ncp->nc_parent) == NULL) return (ENOENT); - cache_hold(fncpd); + fnchd.mount = fromnd->nl_nch.mount; + cache_hold(&fnchd); /* - * unlock the source ncp so we can lookup the target ncp without + * unlock the source nch so we can lookup the target nch without * deadlocking. The target may or may not exist so we do not check * for a target vp like kern_mkdir() and other creation functions do. * @@ -2771,36 +2816,37 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) */ KKASSERT(fromnd->nl_flags & NLC_NCPISLOCKED); fromnd->nl_flags &= ~NLC_NCPISLOCKED; - cache_unlock(fromnd->nl_ncp); + cache_unlock(&fromnd->nl_nch); tond->nl_flags |= NLC_CREATE; if ((error = nlookup(tond)) != 0) { - cache_drop(fncpd); + cache_drop(&fnchd); return (error); } - if ((tncpd = tond->nl_ncp->nc_parent) == NULL) { - cache_drop(fncpd); + if ((tnchd.ncp = tond->nl_nch.ncp->nc_parent) == NULL) { + cache_drop(&fnchd); return (ENOENT); } - cache_hold(tncpd); + tnchd.mount = tond->nl_nch.mount; + cache_hold(&tnchd); /* * If the source and target are the same there is nothing to do */ - if (fromnd->nl_ncp == tond->nl_ncp) { - cache_drop(fncpd); - cache_drop(tncpd); + if (fromnd->nl_nch.ncp == tond->nl_nch.ncp) { + cache_drop(&fnchd); + cache_drop(&tnchd); return (0); } /* * Mount points cannot be renamed or overwritten */ - if ((fromnd->nl_ncp->nc_flag | tond->nl_ncp->nc_flag) & - (NCF_MOUNTPT|NCF_MOUNTEDHERE) + if ((fromnd->nl_nch.ncp->nc_flag | tond->nl_nch.ncp->nc_flag) & + NCF_ISMOUNTPT ) { - cache_drop(fncpd); - cache_drop(tncpd); + cache_drop(&fnchd); + cache_drop(&tnchd); return (EINVAL); } @@ -2809,27 +2855,27 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * may have become invalid while it was unlocked, nc_vp and nc_mount * could be NULL. */ - if (cache_lock_nonblock(fromnd->nl_ncp) == 0) { - cache_resolve(fromnd->nl_ncp, fromnd->nl_cred); - } else if (fromnd->nl_ncp > tond->nl_ncp) { - cache_lock(fromnd->nl_ncp); - cache_resolve(fromnd->nl_ncp, fromnd->nl_cred); + if (cache_lock_nonblock(&fromnd->nl_nch) == 0) { + cache_resolve(&fromnd->nl_nch, fromnd->nl_cred); + } else if (fromnd->nl_nch.ncp > tond->nl_nch.ncp) { + cache_lock(&fromnd->nl_nch); + cache_resolve(&fromnd->nl_nch, fromnd->nl_cred); } else { - cache_unlock(tond->nl_ncp); - cache_lock(fromnd->nl_ncp); - cache_resolve(fromnd->nl_ncp, fromnd->nl_cred); - cache_lock(tond->nl_ncp); - cache_resolve(tond->nl_ncp, tond->nl_cred); + cache_unlock(&tond->nl_nch); + cache_lock(&fromnd->nl_nch); + cache_resolve(&fromnd->nl_nch, fromnd->nl_cred); + cache_lock(&tond->nl_nch); + cache_resolve(&tond->nl_nch, tond->nl_cred); } fromnd->nl_flags |= NLC_NCPISLOCKED; /* * make sure the parent directories linkages are the same */ - if (fncpd != fromnd->nl_ncp->nc_parent || - tncpd != tond->nl_ncp->nc_parent) { - cache_drop(fncpd); - cache_drop(tncpd); + if (fnchd.ncp != fromnd->nl_nch.ncp->nc_parent || + tnchd.ncp != tond->nl_nch.ncp->nc_parent) { + cache_drop(&fnchd); + cache_drop(&tnchd); return (ENOENT); } @@ -2840,20 +2886,20 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * * NOTE: fromnd's nc_mount or nc_vp could be NULL. */ - mp = fncpd->nc_mount; - if (mp != tncpd->nc_mount || mp != fromnd->nl_ncp->nc_mount || - mp != tond->nl_ncp->nc_mount) { - cache_drop(fncpd); - cache_drop(tncpd); + mp = fnchd.mount; + if (mp != tnchd.mount || mp != fromnd->nl_nch.mount || + mp != tond->nl_nch.mount) { + cache_drop(&fnchd); + cache_drop(&tnchd); return (EXDEV); } /* * Make sure the mount point is writable */ - if ((error = ncp_writechk(tond->nl_ncp)) != 0) { - cache_drop(fncpd); - cache_drop(tncpd); + if ((error = ncp_writechk(&tond->nl_nch)) != 0) { + cache_drop(&fnchd); + cache_drop(&tnchd); return (error); } @@ -2861,16 +2907,16 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * If the target exists and either the source or target is a directory, * then both must be directories. * - * Due to relocking of the source, fromnd->nl_ncp->nc_vp might have - * become NULL. + * Due to relocking of the source, fromnd->nl_nch.ncp->nc_vp might h + * have become NULL. */ - if (tond->nl_ncp->nc_vp) { - if (fromnd->nl_ncp->nc_vp == NULL) { + if (tond->nl_nch.ncp->nc_vp) { + if (fromnd->nl_nch.ncp->nc_vp == NULL) { error = ENOENT; - } else if (fromnd->nl_ncp->nc_vp->v_type == VDIR) { - if (tond->nl_ncp->nc_vp->v_type != VDIR) + } else if (fromnd->nl_nch.ncp->nc_vp->v_type == VDIR) { + if (tond->nl_nch.ncp->nc_vp->v_type != VDIR) error = ENOTDIR; - } else if (tond->nl_ncp->nc_vp->v_type == VDIR) { + } else if (tond->nl_nch.ncp->nc_vp->v_type == VDIR) { error = EISDIR; } } @@ -2881,16 +2927,16 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * for a match against the source. */ if (error == 0) { - for (ncp = tncpd; ncp; ncp = ncp->nc_parent) { - if (fromnd->nl_ncp == ncp) { + for (ncp = tnchd.ncp; ncp; ncp = ncp->nc_parent) { + if (fromnd->nl_nch.ncp == ncp) { error = EINVAL; break; } } } - cache_drop(fncpd); - cache_drop(tncpd); + cache_drop(&fnchd); + cache_drop(&tnchd); /* * Even though the namespaces are different, they may still represent @@ -2899,10 +2945,10 @@ kern_rename(struct nlookupdata *fromnd, struct nlookupdata *tond) * when we detect the situation. */ if (error == 0) { - if (fromnd->nl_ncp->nc_vp == tond->nl_ncp->nc_vp) { - error = VOP_NREMOVE(fromnd->nl_ncp, fromnd->nl_cred); + if (fromnd->nl_nch.ncp->nc_vp == tond->nl_nch.ncp->nc_vp) { + error = VOP_NREMOVE(&fromnd->nl_nch, fromnd->nl_cred); } else { - error = VOP_NRENAME(fromnd->nl_ncp, tond->nl_ncp, + error = VOP_NRENAME(&fromnd->nl_nch, &tond->nl_nch, tond->nl_cred); } } @@ -2937,7 +2983,6 @@ kern_mkdir(struct nlookupdata *nd, int mode) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct namecache *ncp; struct vnode *vp; struct vattr vattr; int error; @@ -2947,10 +2992,9 @@ kern_mkdir(struct nlookupdata *nd, int mode) if ((error = nlookup(nd)) != 0) return (error); - ncp = nd->nl_ncp; - if (ncp->nc_vp) + if (nd->nl_nch.ncp->nc_vp) return (EEXIST); - if ((error = ncp_writechk(ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(&vattr); @@ -2958,7 +3002,7 @@ kern_mkdir(struct nlookupdata *nd, int mode) vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask; vp = NULL; - error = VOP_NMKDIR(ncp, &vp, p->p_ucred, &vattr); + error = VOP_NMKDIR(&nd->nl_nch, &vp, p->p_ucred, &vattr); if (error == 0) vput(vp); return (error); @@ -2986,7 +3030,6 @@ sys_mkdir(struct mkdir_args *uap) int kern_rmdir(struct nlookupdata *nd) { - struct namecache *ncp; int error; bwillwrite(); @@ -2999,13 +3042,12 @@ kern_rmdir(struct nlookupdata *nd) * deleted, even if empty. Check write perms on mount point * in case the vnode is aliased (aka nullfs). */ - if (nd->nl_ncp->nc_flag & (NCF_MOUNTEDHERE|NCF_MOUNTPT)) + if (nd->nl_nch.ncp->nc_flag & (NCF_ISMOUNTPT)) return (EINVAL); - if ((error = ncp_writechk(nd->nl_ncp)) != 0) + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); - ncp = nd->nl_ncp; - error = VOP_NRMDIR(ncp, nd->nl_cred); + error = VOP_NRMDIR(&nd->nl_nch, nd->nl_cred); return (error); } @@ -3170,7 +3212,7 @@ sys_revoke(struct revoke_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); cred = crhold(nd.nl_cred); nlookup_done(&nd); if (error == 0) { @@ -3218,7 +3260,7 @@ sys_getfh(struct getfh_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error == 0) { bzero(&fh, sizeof(fh)); @@ -3328,8 +3370,8 @@ sys_fhopen(struct fhopen_args *uap) * VOP_OPEN needs the file pointer so it can potentially override * it. * - * WARNING! no f_ncp will be associated when fhopen()ing a directory. - * XXX + * WARNING! no f_nchandle will be associated when fhopen()ing a + * directory. XXX */ if ((error = falloc(p, &nfp, &indx)) != 0) goto bad; @@ -3468,8 +3510,7 @@ sys_fhstatfs(struct fhstatfs_args *uap) if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) return (ESTALE); - if (p != NULL && (p->p_fd->fd_nrdir->nc_flag & NCF_ROOT) == 0 && - !chroot_visible_mnt(mp, p)) + if (p != NULL && !chroot_visible_mnt(mp, p)) return (ESTALE); if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) @@ -3480,7 +3521,7 @@ sys_fhstatfs(struct fhstatfs_args *uap) if ((error = VFS_STATFS(mp, sp, p->p_ucred)) != 0) return (error); - error = cache_fullpath(p, mp->mnt_ncp, &fullpath, &freepath); + error = cache_fullpath(p, &mp->mnt_ncmountpt, &fullpath, &freepath); if (error) return(error); bzero(sp->f_mntonname, sizeof(sp->f_mntonname)); @@ -3520,7 +3561,7 @@ sys_extattrctl(struct extattrctl_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) { - mp = nd.nl_ncp->nc_mount; + mp = nd.nl_nch.mount; error = VFS_EXTATTRCTL(mp, uap->cmd, uap->attrname, uap->arg, nd.nl_cred); @@ -3559,9 +3600,9 @@ sys_extattr_set_file(struct extattr_set_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = ncp_writechk(nd.nl_ncp); + error = ncp_writechk(&nd.nl_nch); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) { nlookup_done(&nd); return (error); @@ -3638,7 +3679,7 @@ sys_extattr_get_file(struct extattr_get_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) { nlookup_done(&nd); return (error); @@ -3706,9 +3747,9 @@ sys_extattr_delete_file(struct extattr_delete_file_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = ncp_writechk(nd.nl_ncp); + error = ncp_writechk(&nd.nl_nch); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); if (error) { nlookup_done(&nd); return (error); @@ -3720,33 +3761,30 @@ sys_extattr_delete_file(struct extattr_delete_file_args *uap) return(error); } +/* + * Determine if the mount is visible to the process. + */ static int chroot_visible_mnt(struct mount *mp, struct proc *p) { - struct namecache *ncp; + struct nchandle nch; + /* - * First check if this file system is below - * the chroot path. + * Traverse from the mount point upwards. If we hit the process + * root then the mount point is visible to the process. */ - ncp = mp->mnt_ncp; - while (ncp != NULL && ncp != p->p_fd->fd_nrdir) - ncp = ncp->nc_parent; - if (ncp == NULL) { - /* - * This is not below the chroot path. - * - * Check if the chroot path is on the same filesystem, - * by determing if we have to cross a mount point - * before reaching mp->mnt_ncp. - */ - ncp = p->p_fd->fd_nrdir; - while (ncp != NULL && ncp != mp->mnt_ncp) { - if (ncp->nc_flag & NCF_MOUNTPT) { - ncp = NULL; - break; - } - ncp = ncp->nc_parent; + nch = mp->mnt_ncmountpt; + while (nch.ncp) { + if (nch.mount == p->p_fd->fd_nrdir.mount && + nch.ncp == p->p_fd->fd_nrdir.ncp) { + return(1); + } + if (nch.ncp == nch.mount->mnt_ncmountpt.ncp) { + nch = nch.mount->mnt_ncmounton; + } else { + nch.ncp = nch.ncp->nc_parent; } } - return(ncp != NULL); + return(0); } + diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 719f3112f6..3556070f6b 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -37,7 +37,7 @@ * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/vfs_vnops.c,v 1.87.2.13 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.48 2006/09/18 18:19:33 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.49 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -130,12 +130,11 @@ vn_open(struct nlookupdata *nd, struct file *fp, int fmode, int cmode) struct ucred *cred = nd->nl_cred; struct vattr vat; struct vattr *vap = &vat; - struct namecache *ncp; int mode, error; /* * Lookup the path and create or obtain the vnode. After a - * successful lookup a locked nd->nl_ncp will be returned. + * successful lookup a locked nd->nl_nch will be returned. * * The result of this section should be a locked vnode. * @@ -167,7 +166,6 @@ vn_open(struct nlookupdata *nd, struct file *fp, int fmode, int cmode) if (error) return (error); - ncp = nd->nl_ncp; /* * split case to allow us to re-resolve and retry the ncp in case @@ -175,15 +173,15 @@ vn_open(struct nlookupdata *nd, struct file *fp, int fmode, int cmode) */ again: if (fmode & O_CREAT) { - if (ncp->nc_vp == NULL) { - if ((error = ncp_writechk(ncp)) != 0) + if (nd->nl_nch.ncp->nc_vp == NULL) { + if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(vap); vap->va_type = VREG; vap->va_mode = cmode; if (fmode & O_EXCL) vap->va_vaflags |= VA_EXCLUSIVE; - error = VOP_NCREATE(ncp, &vp, nd->nl_cred, vap); + error = VOP_NCREATE(&nd->nl_nch, &vp, nd->nl_cred, vap); if (error) return (error); fmode &= ~O_TRUNC; @@ -192,7 +190,7 @@ again: if (fmode & O_EXCL) { error = EEXIST; } else { - error = cache_vget(ncp, cred, + error = cache_vget(&nd->nl_nch, cred, LK_EXCLUSIVE, &vp); } if (error) @@ -200,14 +198,14 @@ again: fmode &= ~O_CREAT; } } else { - error = cache_vget(ncp, cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd->nl_nch, cred, LK_EXCLUSIVE, &vp); if (error) return (error); } /* * We have a locked vnode and ncp now. Note that the ncp will - * be cleaned up by the caller if nd->nl_ncp is left intact. + * be cleaned up by the caller if nd->nl_nch is left intact. */ if (vp->v_type == VLNK) { error = EMLINK; @@ -224,7 +222,7 @@ again: error = EISDIR; goto bad; } - error = vn_writechk(vp, ncp); + error = vn_writechk(vp, &nd->nl_nch); if (error) { /* * Special stale handling, re-resolve the @@ -233,8 +231,8 @@ again: if (error == ESTALE) { vput(vp); vp = NULL; - cache_setunresolved(ncp); - error = cache_resolve(ncp, cred); + cache_setunresolved(&nd->nl_nch); + error = cache_resolve(&nd->nl_nch, cred); if (error == 0) goto again; } @@ -254,8 +252,8 @@ again: if (error == ESTALE) { vput(vp); vp = NULL; - cache_setunresolved(ncp); - error = cache_resolve(ncp, cred); + cache_setunresolved(&nd->nl_nch); + error = cache_resolve(&nd->nl_nch, cred); if (error == 0) goto again; } @@ -277,27 +275,25 @@ again: * Setup the fp so VOP_OPEN can override it. No descriptor has been * associated with the fp yet so we own it clean. * - * f_ncp inherits nl_ncp. This used to be necessary only for + * f_nchandle inherits nl_nch. This used to be necessary only for * directories but now we do it unconditionally so f*() ops * such as fchmod() can access the actual namespace that was * used to open the file. */ if (fp) { - fp->f_ncp = nd->nl_ncp; - nd->nl_ncp = NULL; - cache_unlock(fp->f_ncp); + fp->f_nchandle = nd->nl_nch; + cache_zero(&nd->nl_nch); + cache_unlock(&fp->f_nchandle); } /* - * Get rid of nl_ncp. vn_open does not return it (it returns the - * vnode or the file pointer). Note: we can't leave nl_ncp locked + * Get rid of nl_nch. vn_open does not return it (it returns the + * vnode or the file pointer). Note: we can't leave nl_nch locked * through the VOP_OPEN anyway since the VOP_OPEN may block, e.g. * on /dev/ttyd0 */ - if (nd->nl_ncp) { - cache_put(nd->nl_ncp); - nd->nl_ncp = NULL; - } + if (nd->nl_nch.ncp) + cache_put(&nd->nl_nch); error = VOP_OPEN(vp, fmode, cred, fp); if (error) { @@ -341,10 +337,10 @@ bad: } /* - * Check for write permissions on the specified vnode. + * Check for write permissions on the specified vnode. nch may be NULL. */ int -vn_writechk(struct vnode *vp, struct namecache *ncp) +vn_writechk(struct vnode *vp, struct nchandle *nch) { /* * If there's shared text associated with @@ -356,14 +352,14 @@ vn_writechk(struct vnode *vp, struct namecache *ncp) /* * If the vnode represents a regular file, check the mount - * point via the ncp. This may be a different mount point + * point via the nch. This may be a different mount point * then the one embedded in the vnode (e.g. nullfs). * * We can still write to non-regular files (e.g. devices) * via read-only mounts. */ - if (ncp && vp->v_type == VREG) - return (ncp_writechk(ncp)); + if (nch && nch->ncp && vp->v_type == VREG) + return (ncp_writechk(nch)); return (0); } @@ -374,9 +370,9 @@ vn_writechk(struct vnode *vp, struct namecache *ncp) * check is needed. */ int -ncp_writechk(struct namecache *ncp) +ncp_writechk(struct nchandle *nch) { - if (ncp->nc_mount && (ncp->nc_mount->mnt_flag & MNT_RDONLY)) + if (nch->mount && (nch->mount->mnt_flag & MNT_RDONLY)) return (EROFS); return(0); } diff --git a/sys/kern/vfs_vopops.c b/sys/kern/vfs_vopops.c index f7912fbbb6..3b33cb32e8 100644 --- a/sys/kern/vfs_vopops.c +++ b/sys/kern/vfs_vopops.c @@ -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.32 2006/08/12 00:26:20 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.33 2006/10/27 04:56:31 dillon Exp $ */ #include @@ -931,14 +931,14 @@ vop_mountctl(struct vop_ops *ops, int op, struct file *fp, * is left locked on return. */ int -vop_nresolve(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred) +vop_nresolve(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred) { struct vop_nresolve_args ap; int error; ap.a_head.a_desc = &vop_nresolve_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_cred = cred; DO_OPS(ops, error, &ap, vop_nresolve); @@ -975,7 +975,7 @@ vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, * is left locked on return. */ int -vop_ncreate(struct vop_ops *ops, struct namecache *ncp, +vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap) { struct vop_ncreate_args ap; @@ -983,7 +983,7 @@ vop_ncreate(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_ncreate_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_vpp = vpp; ap.a_cred = cred; ap.a_vap = vap; @@ -1003,7 +1003,7 @@ vop_ncreate(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nmkdir(struct vop_ops *ops, struct namecache *ncp, +vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap) { struct vop_nmkdir_args ap; @@ -1011,7 +1011,7 @@ vop_nmkdir(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_nmkdir_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_vpp = vpp; ap.a_cred = cred; ap.a_vap = vap; @@ -1031,7 +1031,7 @@ vop_nmkdir(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nmknod(struct vop_ops *ops, struct namecache *ncp, +vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap) { struct vop_nmknod_args ap; @@ -1039,7 +1039,7 @@ vop_nmknod(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_nmknod_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_vpp = vpp; ap.a_cred = cred; ap.a_vap = vap; @@ -1060,7 +1060,7 @@ vop_nmknod(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nlink(struct vop_ops *ops, struct namecache *ncp, +vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *vp, struct ucred *cred) { struct vop_nlink_args ap; @@ -1068,13 +1068,13 @@ vop_nlink(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_nlink_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_vp = vp; ap.a_cred = cred; DO_OPS(ops, error, &ap, vop_nlink); if (error == 0) - cache_update_fsmid(ncp); + cache_update_fsmid(nch); return(error); } @@ -1088,7 +1088,7 @@ vop_nlink(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nsymlink(struct vop_ops *ops, struct namecache *ncp, +vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap, char *target) { @@ -1097,7 +1097,7 @@ vop_nsymlink(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_nsymlink_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_vpp = vpp; ap.a_cred = cred; ap.a_vap = vap; @@ -1105,7 +1105,7 @@ vop_nsymlink(struct vop_ops *ops, struct namecache *ncp, DO_OPS(ops, error, &ap, vop_nsymlink); if (error == 0) - cache_update_fsmid(ncp); + cache_update_fsmid(nch); return(error); } @@ -1117,7 +1117,7 @@ vop_nsymlink(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nwhiteout(struct vop_ops *ops, struct namecache *ncp, +vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred, int flags) { struct vop_nwhiteout_args ap; @@ -1125,13 +1125,13 @@ vop_nwhiteout(struct vop_ops *ops, struct namecache *ncp, ap.a_head.a_desc = &vop_nwhiteout_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_cred = cred; ap.a_flags = flags; DO_OPS(ops, error, &ap, vop_nwhiteout); if (error == 0) - cache_update_fsmid(ncp); + cache_update_fsmid(nch); return(error); } @@ -1143,19 +1143,19 @@ vop_nwhiteout(struct vop_ops *ops, struct namecache *ncp, * is left locked on return. */ int -vop_nremove(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred) +vop_nremove(struct vop_ops *ops, struct nchandle *nch, 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_nch = nch; ap.a_cred = cred; DO_OPS(ops, error, &ap, vop_nremove); if (error == 0) - cache_update_fsmid(ncp); + cache_update_fsmid(nch); return(error); } @@ -1167,19 +1167,19 @@ vop_nremove(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred) * is left locked on return. */ int -vop_nrmdir(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred) +vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred) { struct vop_nrmdir_args ap; int error; ap.a_head.a_desc = &vop_nrmdir_desc; ap.a_head.a_ops = ops; - ap.a_ncp = ncp; + ap.a_nch = nch; ap.a_cred = cred; DO_OPS(ops, error, &ap, vop_nrmdir); if (error == 0) - cache_update_fsmid(ncp); + cache_update_fsmid(nch); return(error); } @@ -1194,22 +1194,22 @@ vop_nrmdir(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred) * source ncp's underlying file. */ int -vop_nrename(struct vop_ops *ops, struct namecache *fncp, - struct namecache *tncp, struct ucred *cred) +vop_nrename(struct vop_ops *ops, struct nchandle *fnch, + struct nchandle *tnch, struct ucred *cred) { struct vop_nrename_args ap; int error; ap.a_head.a_desc = &vop_nrename_desc; ap.a_head.a_ops = ops; - ap.a_fncp = fncp; - ap.a_tncp = tncp; + ap.a_fnch = fnch; + ap.a_tnch = tnch; ap.a_cred = cred; DO_OPS(ops, error, &ap, vop_nrename); if (error == 0) { - cache_update_fsmid(fncp); - cache_update_fsmid(tncp); + cache_update_fsmid(fnch); + cache_update_fsmid(tnch); } return(error); } diff --git a/sys/sys/file.h b/sys/sys/file.h index e164dceb23..00d3f8c44c 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -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.23 2006/08/06 18:56:46 dillon Exp $ + * $DragonFly: src/sys/sys/file.h,v 1.24 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_FILE_H_ @@ -56,6 +56,9 @@ #ifndef _SYS_SPINLOCK_H_ #include #endif +#ifndef _SYS_NAMECACHE_H_ +#include +#endif struct stat; struct proc; @@ -111,7 +114,7 @@ struct file { void *f_data; /* vnode, pipe, socket, or kqueue */ int f_count; /* reference count */ int f_msgcount; /* (U) reference count from message queue */ - struct namecache *f_ncp; /* ncp (required for directories) */ + struct nchandle f_nchandle; /* namecache reference */ struct spinlock f_spin; }; diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index e3592c7bbc..d57e9d8791 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -32,7 +32,7 @@ * * @(#)filedesc.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: src/sys/sys/filedesc.h,v 1.19.2.5 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/sys/filedesc.h,v 1.19 2006/05/26 02:26:26 dillon Exp $ + * $DragonFly: src/sys/sys/filedesc.h,v 1.20 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_FILEDESC_H_ @@ -47,6 +47,9 @@ #ifndef _SYS_SPINLOCK_H_ #include #endif +#ifndef _SYS_NAMECACHE_H_ +#include +#endif /* * This structure is used for the management of descriptors. It may be @@ -65,7 +68,6 @@ struct file; struct klist; -struct namecache; struct fdnode { struct file *fp; @@ -81,9 +83,9 @@ struct filedesc { struct vnode *fd_cdir; /* current directory (phaseout) */ struct vnode *fd_rdir; /* root directory (phaseout) */ struct vnode *fd_jdir; /* jail root directory (phaseout) */ - struct namecache *fd_ncdir; /* current directory */ - struct namecache *fd_nrdir; /* root directory */ - struct namecache *fd_njdir; /* jail directory */ + struct nchandle fd_ncdir; /* current directory */ + struct nchandle fd_nrdir; /* root directory */ + struct nchandle fd_njdir; /* jail directory */ int fd_nfiles; /* number of open files allocated */ int fd_lastfile; /* high-water mark of fd_files */ int fd_freefile; /* approx. next free file */ diff --git a/sys/sys/jail.h b/sys/sys/jail.h index 48e1ac0793..5bff01aab2 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -7,7 +7,7 @@ * ---------------------------------------------------------------------------- * * $FreeBSD: src/sys/sys/jail.h,v 1.8.2.2 2000/11/01 17:58:06 rwatson Exp $ - * $DragonFly: src/sys/sys/jail.h,v 1.7 2006/05/20 02:42:13 dillon Exp $ + * $DragonFly: src/sys/sys/jail.h,v 1.8 2006/10/27 04:56:33 dillon Exp $ * */ @@ -38,7 +38,12 @@ int jail_attach(int); #else /* _KERNEL */ +#ifndef _SYS_NAMECACHE_H_ +#include +#endif +#ifndef _SYS_VARSYM_H_ #include +#endif #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_PRISON); @@ -56,7 +61,7 @@ struct prison { LIST_ENTRY(prison) pr_list; /* all prisons */ int pr_id; /* prison id */ int pr_ref; /* reference count */ - struct namecache *pr_root; /* namecache entry of root */ + struct nchandle pr_root; /* namecache entry of root */ char pr_host[MAXHOSTNAMELEN]; /* host name */ uint32_t pr_ip; /* IP address */ void *pr_linux; /* Linux ABI emulation */ diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index f019f851a0..882f2d2d23 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -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.33 2006/09/17 21:09:39 dillon Exp $ + * $DragonFly: src/sys/sys/kern_syscall.h,v 1.34 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_KERN_SYSCALL_H_ @@ -44,6 +44,7 @@ struct plimit; struct mbuf; struct msghdr; struct namecache; +struct nchandle; struct nlookupdata; struct rlimit; struct rusage; @@ -131,7 +132,7 @@ int kern_access(struct nlookupdata *nd, int aflags); int kern_chdir(struct nlookupdata *nd); int kern_chmod(struct nlookupdata *nd, int mode); int kern_chown(struct nlookupdata *nd, int uid, int gid); -int kern_chroot(struct namecache *ncp); +int kern_chroot(struct nchandle *nch); int kern_fstatfs(int fd, struct statfs *buf); int kern_ftruncate(int fd, off_t length); int kern_futimes(int fd, struct timeval *tptr); diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 13dd6a33f0..dece19260d 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -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.29 2006/09/19 16:06:12 dillon Exp $ + * $DragonFly: src/sys/sys/mount.h,v 1.30 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -53,6 +53,9 @@ #ifndef _SYS_LOCK_H_ #include #endif +#ifndef _SYS_NAMECACHE_H_ +#include +#endif #endif struct thread; @@ -157,7 +160,9 @@ struct mount { struct vop_ops *mnt_vn_norm_ops; /* for use by the VFS */ struct vop_ops *mnt_vn_spec_ops; /* for use by the VFS */ struct vop_ops *mnt_vn_fifo_ops; /* for use by the VFS */ - struct namecache *mnt_ncp; /* NCF_MNTPT ncp */ + struct nchandle mnt_ncmountpt; /* mount point */ + struct nchandle mnt_ncmounton; /* mounted on */ + int mnt_refs; /* nchandle references */ struct journallst mnt_jlist; /* list of active journals */ u_int8_t *mnt_jbitmap; /* streamid bitmap */ @@ -240,6 +245,7 @@ struct mount { * with the unmount attempt (used by NFS). */ #define MNTK_UNMOUNTF 0x00000001 /* forced unmount in progress */ +#define MNTK_NCALIASED 0x00800000 /* namecached aliased */ #define MNTK_UNMOUNT 0x01000000 /* unmount in progress */ #define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */ #define MNTK_WANTRDWR 0x04000000 /* upgrade to read/write requested */ diff --git a/sys/sys/namecache.h b/sys/sys/namecache.h index fe033b4d7a..333ad1ead9 100644 --- a/sys/sys/namecache.h +++ b/sys/sys/namecache.h @@ -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.27 2006/09/19 16:06:12 dillon Exp $ + * $DragonFly: src/sys/sys/namecache.h,v 1.28 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_NAMECACHE_H_ @@ -121,11 +121,17 @@ struct namecache { int nc_timeout; /* compared against ticks, or 0 */ int nc_exlocks; /* namespace locking */ struct thread *nc_locktd; /* namespace locking */ - struct mount *nc_mount; /* associated mount for vopops */ int64_t nc_fsmid; /* filesystem modified id */ }; -typedef struct namecache *namecache_t; +/* + * Namecache handles include a mount reference allowing topologies + * to be replicated with mount overlays (nullfs mounts). + */ +struct nchandle { + struct namecache *ncp; /* ncp in underlying filesystem */ + struct mount *mount; /* mount pt (possible overlay) */ +}; /* * Flags in namecache.nc_flag (u_char) @@ -133,11 +139,11 @@ typedef struct namecache *namecache_t; #define NCF_LOCKED 0x0001 /* locked namespace */ #define NCF_WHITEOUT 0x0002 /* negative entry corresponds to whiteout */ #define NCF_UNRESOLVED 0x0004 /* invalid or unresolved entry */ -#define NCF_MOUNTPT 0x0008 /* mount point */ -#define NCF_ROOT 0x0010 /* namecache root (static) */ +#define NCF_ISMOUNTPT 0x0008 /* someone may have mounted on us here */ +#define NCF_UNUSED10 0x0010 #define NCF_HASHED 0x0020 /* namecache entry in hash table */ #define NCF_LOCKREQ 0x0040 -#define NCF_MOUNTEDHERE 0x0080 /* has child marked NCF_MOUNTPT */ +#define NCF_UNUSED20 0x0080 #define NCF_ISSYMLINK 0x0100 /* represents a symlink */ #define NCF_ISDIR 0x0200 /* represents a directory */ #define NCF_DESTROYED 0x0400 /* name association is considered destroyed */ @@ -156,38 +162,38 @@ struct componentname; struct nlcomponent; struct mount; -void cache_lock(struct namecache *ncp); -int cache_lock_nonblock(struct namecache *ncp); -void cache_unlock(struct namecache *ncp); -void cache_setvp(struct namecache *ncp, struct vnode *vp); -void cache_settimeout(struct namecache *ncp, int nticks); -void cache_setunresolved(struct namecache *ncp); -void cache_setmountpt(struct namecache *ncp, struct mount *mp); -void cache_clrmountpt(struct namecache *ncp); -struct namecache *cache_nlookup(struct namecache *par, struct nlcomponent *nlc); -struct namecache *cache_allocroot(struct mount *mp, struct vnode *vp); -struct mount *cache_findmount(struct namecache *par); -int cache_inval(struct namecache *ncp, int flags); +void cache_lock(struct nchandle *nch); +int cache_lock_nonblock(struct nchandle *nch); +void cache_unlock(struct nchandle *nch); +void cache_setvp(struct nchandle *nch, struct vnode *vp); +void cache_settimeout(struct nchandle *nch, int nticks); +void cache_setunresolved(struct nchandle *nch); +void cache_clrmountpt(struct nchandle *nch); +struct nchandle cache_nlookup(struct nchandle *nch, struct nlcomponent *nlc); +void cache_allocroot(struct nchandle *nch, struct mount *mp, struct vnode *vp); +struct mount *cache_findmount(struct nchandle *nch); +int cache_inval(struct nchandle *nch, int flags); int cache_inval_vp(struct vnode *vp, int flags); -void vfs_cache_setroot(struct vnode *vp, struct namecache *ncp); - +void vfs_cache_setroot(struct vnode *vp, struct nchandle *nch); -int cache_resolve(struct namecache *ncp, struct ucred *cred); +int cache_resolve(struct nchandle *nch, struct ucred *cred); void cache_purge(struct vnode *vp); void cache_purgevfs (struct mount *mp); -void cache_validate(struct namecache *ncp); -int cache_get_nonblock(struct namecache *ncp); +int cache_get_nonblock(struct nchandle *nch); void cache_cleanneg(int count); -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); -void cache_rename(struct namecache *fncp, struct namecache *tncp); -int cache_vget(struct namecache *, struct ucred *, int, struct vnode **); -int cache_vref(struct namecache *, struct ucred *, struct vnode **); -struct namecache *cache_fromdvp(struct vnode *, struct ucred *, int); -int cache_fullpath(struct proc *, struct namecache *, char **, char **); -void cache_update_fsmid(struct namecache *); +void cache_get(struct nchandle *nch, struct nchandle *target); +struct nchandle *cache_hold(struct nchandle *nch); +void cache_copy(struct nchandle *nch, struct nchandle *target); +void cache_changemount(struct nchandle *nch, struct mount *mp); +void cache_put(struct nchandle *nch); +void cache_drop(struct nchandle *nch); +void cache_zero(struct nchandle *nch); +void cache_rename(struct nchandle *fnch, struct nchandle *tnch); +int cache_vget(struct nchandle *, struct ucred *, int, struct vnode **); +int cache_vref(struct nchandle *, struct ucred *, struct vnode **); +int cache_fromdvp(struct vnode *, struct ucred *, int, struct nchandle *); +int cache_fullpath(struct proc *, struct nchandle *, char **, char **); +void cache_update_fsmid(struct nchandle *); void cache_update_fsmid_vp(struct vnode *); int64_t cache_sync_fsmid_vp(struct vnode *); int cache_check_fsmid_vp(struct vnode *, int64_t *); diff --git a/sys/sys/nlookup.h b/sys/sys/nlookup.h index d0add0fb75..699082430c 100644 --- a/sys/sys/nlookup.h +++ b/sys/sys/nlookup.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/nlookup.h,v 1.4 2005/03/09 06:11:22 hmp Exp $ + * $DragonFly: src/sys/sys/nlookup.h,v 1.5 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_NLOOKUP_H_ @@ -40,11 +40,13 @@ #ifndef _SYS_UIO_H_ #include #endif +#ifndef _SYS_NAMECACHE_H_ +#include +#endif struct vnode; struct vattr; struct mount; -struct namecache; struct thread; struct ucred; @@ -66,14 +68,14 @@ struct nlcomponent { */ struct nlookupdata { /* - * These fields are setup by nlookup_init() with nl_ncp set to + * These fields are setup by nlookup_init() with nl_nch set to * the current directory if a process or the root directory if * a pure thread. The result from nlookup() will be returned in - * nl_ncp. + * nl_nch. */ - struct namecache *nl_ncp; /* start-point and result */ - struct namecache *nl_rootncp; /* root directory */ - struct namecache *nl_jailncp; /* jail directory */ + struct nchandle nl_nch; /* start-point and result */ + struct nchandle nl_rootnch; /* root directory */ + struct nchandle nl_jailnch; /* jail directory */ char *nl_path; /* path buffer */ struct thread *nl_td; /* thread requesting the nlookup */ @@ -106,17 +108,17 @@ struct nlookupdata { #ifdef _KERNEL int nlookup_init(struct nlookupdata *, const char *, enum uio_seg, int); -int nlookup_init_raw(struct nlookupdata *, const char *, enum uio_seg, int, struct ucred *, struct namecache *); +int nlookup_init_raw(struct nlookupdata *, const char *, enum uio_seg, int, struct ucred *, struct nchandle *); void nlookup_set_cred(struct nlookupdata *nd, struct ucred *cred); void nlookup_zero(struct nlookupdata *); void nlookup_done(struct nlookupdata *); -struct namecache *nlookup_simple(const char *str, enum uio_seg seg, +struct nchandle nlookup_simple(const char *str, enum uio_seg seg, int niflags, int *error); -int nlookup_mp(struct mount *mp, struct namecache **ncpp); +int nlookup_mp(struct mount *mp, struct nchandle *nch); int nlookup(struct nlookupdata *); -int nreadsymlink(struct nlookupdata *nd, struct namecache *ncp, +int nreadsymlink(struct nlookupdata *nd, struct nchandle *nch, struct nlcomponent *nlc); -int naccess(struct namecache *ncp, int vmode, struct ucred *cred); +int naccess(struct nchandle *nch, int vmode, struct ucred *cred); int naccess_va(struct vattr *va, int vmode, struct ucred *cred); #endif diff --git a/sys/sys/vfsops.h b/sys/sys/vfsops.h index a50ca32428..72f17fcabd 100644 --- a/sys/sys/vfsops.h +++ b/sys/sys/vfsops.h @@ -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.26 2006/08/12 00:26:20 dillon Exp $ + * $DragonFly: src/sys/sys/vfsops.h,v 1.27 2006/10/27 04:56:33 dillon Exp $ */ /* @@ -71,7 +71,7 @@ struct syslink_desc; struct vnode; struct thread; -struct namecache; +struct nchandle; struct componentname; struct vattr; struct ucred; @@ -419,7 +419,7 @@ struct vop_mountctl_args { */ struct vop_nresolve_args { struct vop_generic_args a_head; - struct namecache *a_ncp; + struct nchandle *a_nch; struct ucred *a_cred; }; @@ -432,7 +432,7 @@ struct vop_nlookupdotdot_args { struct vop_ncreate_args { struct vop_generic_args a_head; - struct namecache *a_ncp; /* locked namespace */ + struct nchandle *a_nch; /* locked namespace */ struct vnode **a_vpp; /* returned refd & locked */ struct ucred *a_cred; struct vattr *a_vap; @@ -440,7 +440,7 @@ struct vop_ncreate_args { struct vop_nmkdir_args { struct vop_generic_args a_head; - struct namecache *a_ncp; /* locked namespace */ + struct nchandle *a_nch; /* locked namespace */ struct vnode **a_vpp; /* returned refd & locked */ struct ucred *a_cred; struct vattr *a_vap; @@ -448,7 +448,7 @@ struct vop_nmkdir_args { struct vop_nmknod_args { struct vop_generic_args a_head; - struct namecache *a_ncp; + struct nchandle *a_nch; struct vnode **a_vpp; struct ucred *a_cred; struct vattr *a_vap; @@ -456,14 +456,14 @@ struct vop_nmknod_args { struct vop_nlink_args { struct vop_generic_args a_head; - struct namecache *a_ncp; + struct nchandle *a_nch; struct vnode *a_vp; struct ucred *a_cred; }; struct vop_nsymlink_args { struct vop_generic_args a_head; - struct namecache *a_ncp; + struct nchandle *a_nch; struct vnode **a_vpp; struct ucred *a_cred; struct vattr *a_vap; @@ -472,27 +472,27 @@ struct vop_nsymlink_args { struct vop_nwhiteout_args { struct vop_generic_args a_head; - struct namecache *a_ncp; + struct nchandle *a_nch; struct ucred *a_cred; int a_flags; }; struct vop_nremove_args { struct vop_generic_args a_head; - struct namecache *a_ncp; /* locked namespace */ + struct nchandle *a_nch; /* locked namespace */ struct ucred *a_cred; }; struct vop_nrmdir_args { struct vop_generic_args a_head; - struct namecache *a_ncp; /* locked namespace */ + struct nchandle *a_nch; /* locked namespace */ struct ucred *a_cred; }; struct vop_nrename_args { struct vop_generic_args a_head; - struct namecache *a_fncp; /* locked namespace / from */ - struct namecache *a_tncp; /* locked namespace / to */ + struct nchandle *a_fnch; /* locked namespace / from */ + struct nchandle *a_tnch; /* locked namespace / to */ struct ucred *a_cred; }; @@ -746,29 +746,29 @@ int vop_setextattr(struct vop_ops *ops, struct vnode *vp, char *name, struct uio *uio, struct ucred *cred); int vop_mountctl(struct vop_ops *ops, int op, struct file *fp, const void *ctl, int ctllen, void *buf, int buflen, int *res); -int vop_nresolve(struct vop_ops *ops, struct namecache *ncp, +int vop_nresolve(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred); int vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, struct vnode **vpp, struct ucred *cred); -int vop_ncreate(struct vop_ops *ops, struct namecache *ncp, +int vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap); -int vop_nmkdir(struct vop_ops *ops, struct namecache *ncp, +int vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap); -int vop_nmknod(struct vop_ops *ops, struct namecache *ncp, +int vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap); -int vop_nlink(struct vop_ops *ops, struct namecache *ncp, struct vnode *vp, +int vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *vp, struct ucred *cred); -int vop_nsymlink(struct vop_ops *ops, struct namecache *ncp, +int vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode **vpp, struct ucred *cred, struct vattr *vap, char *target); -int vop_nwhiteout(struct vop_ops *ops, struct namecache *ncp, +int vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred, int flags); -int vop_nremove(struct vop_ops *ops, struct namecache *ncp, +int vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred); -int vop_nrmdir(struct vop_ops *ops, struct namecache *ncp, +int vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct ucred *cred); -int vop_nrename(struct vop_ops *ops, struct namecache *fncp, - struct namecache *tncp, struct ucred *cred); +int vop_nrename(struct vop_ops *ops, struct nchandle *fnch, + struct nchandle *tnch, struct ucred *cred); /* * Kernel VOP forwarding wrappers. These are called when a VFS such as @@ -1006,26 +1006,26 @@ extern struct syslink_desc vop_nrename_desc; * code in kern/vfs_default which does the magic required to call the old * routines. */ -#define VOP_NRESOLVE(ncp, cred) \ - vop_nresolve((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred) -#define VOP_NCREATE(ncp, vpp, cred, vap) \ - vop_ncreate((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap) -#define VOP_NMKDIR(ncp, vpp, cred, vap) \ - vop_nmkdir((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap) -#define VOP_NMKNOD(ncp, vpp, cred, vap) \ - vop_nmknod((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap) -#define VOP_NLINK(ncp, vp, cred) \ - vop_nlink((ncp)->nc_mount->mnt_vn_use_ops, ncp, vp, cred) -#define VOP_NSYMLINK(ncp, vpp, cred, vap, target) \ - vop_nsymlink((ncp)->nc_mount->mnt_vn_use_ops, ncp, vpp, cred, vap, target) -#define VOP_NWHITEOUT(ncp, cred, flags) \ - vop_nwhiteout((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred, flags) -#define VOP_NRENAME(fncp, tncp, cred) \ - vop_nrename((fncp)->nc_mount->mnt_vn_use_ops, fncp, tncp, cred) -#define VOP_NRMDIR(ncp, cred) \ - vop_nrmdir((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred) -#define VOP_NREMOVE(ncp, cred) \ - vop_nremove((ncp)->nc_mount->mnt_vn_use_ops, ncp, cred) +#define VOP_NRESOLVE(nch, cred) \ + vop_nresolve((nch)->mount->mnt_vn_use_ops, nch, cred) +#define VOP_NCREATE(nch, vpp, cred, vap) \ + vop_ncreate((nch)->mount->mnt_vn_use_ops, nch, vpp, cred, vap) +#define VOP_NMKDIR(nch, vpp, cred, vap) \ + vop_nmkdir((nch)->mount->mnt_vn_use_ops, nch, vpp, cred, vap) +#define VOP_NMKNOD(nch, vpp, cred, vap) \ + vop_nmknod((nch)->mount->mnt_vn_use_ops, nch, vpp, cred, vap) +#define VOP_NLINK(nch, vp, cred) \ + vop_nlink((nch)->mount->mnt_vn_use_ops, nch, vp, cred) +#define VOP_NSYMLINK(nch, vpp, cred, vap, target) \ + vop_nsymlink((nch)->mount->mnt_vn_use_ops, nch, vpp, cred, vap, target) +#define VOP_NWHITEOUT(nch, cred, flags) \ + vop_nwhiteout((nch)->mount->mnt_vn_use_ops, nch, cred, flags) +#define VOP_NRENAME(fnch, tnch, cred) \ + vop_nrename((fnch)->mount->mnt_vn_use_ops, fnch, tnch, cred) +#define VOP_NRMDIR(nch, cred) \ + vop_nrmdir((nch)->mount->mnt_vn_use_ops, nch, cred) +#define VOP_NREMOVE(nch, cred) \ + vop_nremove((nch)->mount->mnt_vn_use_ops, nch, cred) #endif diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 74e26883f0..ef43a56261 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -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.71 2006/09/19 16:06:12 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.72 2006/10/27 04:56:33 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -372,7 +372,7 @@ extern int vttoif_tab[]; struct objcache; extern struct vnode *rootvnode; /* root (i.e. "/") vnode */ -extern struct namecache *rootncp; /* root (i.e. "/") namecache */ +extern struct nchandle rootnch; /* 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 */ @@ -507,8 +507,8 @@ int vn_rdwr_inchunks (enum uio_rw rw, struct vnode *vp, caddr_t base, int vn_stat (struct vnode *vp, struct stat *sb, struct ucred *cred); cdev_t vn_todev (struct vnode *vp); void vfs_timestamp (struct timespec *); -int vn_writechk (struct vnode *vp, struct namecache *ncp); -int ncp_writechk(struct namecache *ncp); +int vn_writechk (struct vnode *vp, struct nchandle *nch); +int ncp_writechk(struct nchandle *nch); int vop_stdopen (struct vop_open_args *ap); int vop_stdclose (struct vop_close_args *ap); int vop_nopoll (struct vop_poll_args *ap); diff --git a/sys/vfs/gnu/ext2fs/ext2_vfsops.c b/sys/vfs/gnu/ext2fs/ext2_vfsops.c index bfd2b9cd4e..af07384be9 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vfsops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vfsops.c @@ -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.50 2006/09/10 01:26:40 dillon Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.51 2006/10/27 04:56:33 dillon Exp $ */ #include "opt_quota.h" @@ -340,7 +340,7 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/vfs/hpfs/hpfs_vfsops.c b/sys/vfs/hpfs/hpfs_vfsops.c index 5b330790f6..c08ac9febd 100644 --- a/sys/vfs/hpfs/hpfs_vfsops.c +++ b/sys/vfs/hpfs/hpfs_vfsops.c @@ -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.38 2006/09/10 01:26:40 dillon Exp $ + * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.39 2006/10/27 04:56:34 dillon Exp $ */ @@ -169,7 +169,7 @@ hpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) goto error_1; diff --git a/sys/vfs/isofs/cd9660/cd9660_rrip.c b/sys/vfs/isofs/cd9660/cd9660_rrip.c index e698c6003f..5be431e0ff 100644 --- a/sys/vfs/isofs/cd9660/cd9660_rrip.c +++ b/sys/vfs/isofs/cd9660/cd9660_rrip.c @@ -37,7 +37,7 @@ * * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94 * $FreeBSD: src/sys/isofs/cd9660/cd9660_rrip.c,v 1.17 1999/08/28 00:46:06 peter Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_rrip.c,v 1.11 2006/09/05 00:55:50 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_rrip.c,v 1.12 2006/10/27 04:56:34 dillon Exp $ */ #include @@ -174,7 +174,7 @@ cd9660_rrip_slink(ISO_RRIP_SLINK *p, ISO_RRIP_ANALYZE *ana) /* same as above */ outbuf -= len; len = 0; - error = cache_fullpath(NULL, ana->imp->im_mountp->mnt_ncp, + error = cache_fullpath(NULL, &ana->imp->im_mountp->mnt_ncmountpt, &inbuf, &freebuf); if (error) goto bad; diff --git a/sys/vfs/isofs/cd9660/cd9660_vfsops.c b/sys/vfs/isofs/cd9660/cd9660_vfsops.c index b675380676..b2e76cdc3c 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c @@ -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.41 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.42 2006/10/27 04:56:34 dillon Exp $ */ #include @@ -212,7 +212,7 @@ cd9660_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/vfs/msdosfs/msdosfs_vfsops.c b/sys/vfs/msdosfs/msdosfs_vfsops.c index f8d1a6ec35..f1feca3a27 100644 --- a/sys/vfs/msdosfs/msdosfs_vfsops.c +++ b/sys/vfs/msdosfs/msdosfs_vfsops.c @@ -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.41 2006/10/03 01:32:41 swildner Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.42 2006/10/27 04:56:34 dillon Exp $ */ /* $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $ */ /*- @@ -236,7 +236,7 @@ msdosfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/vfs/nfs/nfs_serv.c b/sys/vfs/nfs/nfs_serv.c index c74bbbbcc5..c920498e8b 100644 --- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -35,7 +35,7 @@ * * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95 * $FreeBSD: src/sys/nfs/nfs_serv.c,v 1.93.2.6 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.40 2006/09/19 16:06:14 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.41 2006/10/27 04:56:34 dillon Exp $ */ /* @@ -424,7 +424,7 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nlookupdata nd; struct vnode *vp; struct vnode *dirp; - struct namecache *ncp; + struct nchandle nch; nfsfh_t nfh; fhandle_t *fhp; caddr_t cp; @@ -492,11 +492,11 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * via the original nd. Confused? You aren't alone! */ vn_unlock(vp); - ncp = cache_hold(nd.nl_ncp); + cache_copy(&nd.nl_nch, &nch); nlookup_done(&nd); error = nlookup_init_raw(&nd, nfs_pub.np_index, - UIO_SYSSPACE, 0, cred, ncp); - cache_drop(ncp); + UIO_SYSSPACE, 0, cred, &nch); + cache_drop(&nch); if (error == 0) error = nlookup(&nd); @@ -512,7 +512,7 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vrele(dirp); dirp = vp; vp = NULL; - error = cache_vget(nd.nl_ncp, nd.nl_cred, + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); KKASSERT(error == 0); } @@ -1663,7 +1663,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (vap->va_type == VREG || vap->va_type == VSOCK) { vput(dvp); dvp = NULL; - error = VOP_NCREATE(nd.nl_ncp, &vp, nd.nl_cred, vap); + error = VOP_NCREATE(&nd.nl_nch, &vp, nd.nl_cred, vap); if (error == 0) { if (exclusive_flag) { exclusive_flag = 0; @@ -1692,7 +1692,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vput(dvp); dvp = NULL; - error = VOP_NMKNOD(nd.nl_ncp, &vp, nd.nl_cred, vap); + error = VOP_NMKNOD(&nd.nl_nch, &vp, nd.nl_cred, vap); if (error) goto nfsmreply0; #if 0 @@ -1880,12 +1880,12 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; if (vtyp == VSOCK) { - error = VOP_NCREATE(nd.nl_ncp, &vp, nd.nl_cred, vap); + error = VOP_NCREATE(&nd.nl_nch, &vp, nd.nl_cred, vap); } else { if (vtyp != VFIFO && (error = suser_cred(cred, 0))) goto out; - error = VOP_NMKNOD(nd.nl_ncp, &vp, nd.nl_cred, vap); + error = VOP_NMKNOD(&nd.nl_nch, &vp, nd.nl_cred, vap); if (error) goto out; @@ -2036,7 +2036,7 @@ out: vput(vp); vp = NULL; } - error = VOP_NREMOVE(nd.nl_ncp, nd.nl_cred); + error = VOP_NREMOVE(&nd.nl_nch, nd.nl_cred); } } if (dirp && v3) @@ -2132,7 +2132,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * the target ncp. */ KKASSERT(fromnd.nl_flags & NLC_NCPISLOCKED); - cache_unlock(fromnd.nl_ncp); + cache_unlock(&fromnd.nl_nch); fromnd.nl_flags &= ~NLC_NCPISLOCKED; nfsm_srvmtofh(tfhp); nfsm_strsiz(len2, NFS_MAXNAMLEN); @@ -2151,22 +2151,22 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, /* * relock the source */ - if (cache_lock_nonblock(fromnd.nl_ncp) == 0) { - cache_resolve(fromnd.nl_ncp, fromnd.nl_cred); - } else if (fromnd.nl_ncp > tond.nl_ncp) { - cache_lock(fromnd.nl_ncp); - cache_resolve(fromnd.nl_ncp, fromnd.nl_cred); + if (cache_lock_nonblock(&fromnd.nl_nch) == 0) { + cache_resolve(&fromnd.nl_nch, fromnd.nl_cred); + } else if (fromnd.nl_nch.ncp > tond.nl_nch.ncp) { + cache_lock(&fromnd.nl_nch); + cache_resolve(&fromnd.nl_nch, fromnd.nl_cred); } else { - cache_unlock(tond.nl_ncp); - cache_lock(fromnd.nl_ncp); - cache_resolve(fromnd.nl_ncp, fromnd.nl_cred); - cache_lock(tond.nl_ncp); - cache_resolve(tond.nl_ncp, tond.nl_cred); + cache_unlock(&tond.nl_nch); + cache_lock(&fromnd.nl_nch); + cache_resolve(&fromnd.nl_nch, fromnd.nl_cred); + cache_lock(&tond.nl_nch); + cache_resolve(&tond.nl_nch, tond.nl_cred); } fromnd.nl_flags |= NLC_NCPISLOCKED; - tvp = tond.nl_ncp->nc_vp; - fvp = fromnd.nl_ncp->nc_vp; + tvp = tond.nl_nch.ncp->nc_vp; + fvp = fromnd.nl_nch.ncp->nc_vp; if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { @@ -2182,7 +2182,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = ENOTDIR; goto out; } - if (tvp->v_type == VDIR && (tond.nl_ncp->nc_flag & NCF_MOUNTPT)) { + if (tvp->v_type == VDIR && (tond.nl_nch.ncp->nc_flag & NCF_ISMOUNTPT)) { if (v3) error = EXDEV; else @@ -2190,21 +2190,21 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, goto out; } } - if (fvp->v_type == VDIR && (fromnd.nl_ncp->nc_flag & NCF_MOUNTPT)) { + if (fvp->v_type == VDIR && (fromnd.nl_nch.ncp->nc_flag & NCF_ISMOUNTPT)) { if (v3) error = EXDEV; else error = ENOTEMPTY; goto out; } - if (fromnd.nl_ncp->nc_mount != tond.nl_ncp->nc_mount) { + if (fromnd.nl_nch.mount != tond.nl_nch.mount) { if (v3) error = EXDEV; else error = ENOTEMPTY; goto out; } - if (fromnd.nl_ncp == tond.nl_ncp->nc_parent) { + if (fromnd.nl_nch.ncp == tond.nl_nch.ncp->nc_parent) { if (v3) error = EINVAL; else @@ -2217,8 +2217,8 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * for a match against the source. */ if (error == 0) { - for (ncp = tond.nl_ncp; ncp; ncp = ncp->nc_parent) { - if (fromnd.nl_ncp == ncp) { + for (ncp = tond.nl_nch.ncp; ncp; ncp = ncp->nc_parent) { + if (fromnd.nl_nch.ncp == ncp) { error = EINVAL; break; } @@ -2230,7 +2230,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * same vnode with the same name in the same directory), * then there is nothing to do. */ - if (fromnd.nl_ncp == tond.nl_ncp) + if (fromnd.nl_nch.ncp == tond.nl_nch.ncp) error = -1; out: if (!error) { @@ -2239,7 +2239,7 @@ out: * locks prior to returning so we need to clear the pointers * to bypass cleanup code later on. */ - error = VOP_NRENAME(fromnd.nl_ncp, tond.nl_ncp, tond.nl_cred); + error = VOP_NRENAME(&fromnd.nl_nch, &tond.nl_nch, tond.nl_cred); } else { if (error == -1) error = 0; @@ -2339,7 +2339,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = EXDEV; out: if (!error) { - error = VOP_NLINK(nd.nl_ncp, xp, nd.nl_cred); + error = VOP_NLINK(&nd.nl_nch, xp, nd.nl_cred); } /* fall through */ @@ -2446,7 +2446,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; - error = VOP_NSYMLINK(nd.nl_ncp, &vp, nd.nl_cred, vap, pathcp); + error = VOP_NSYMLINK(&nd.nl_nch, &vp, nd.nl_cred, vap, pathcp); if (error == 0) { bzero((caddr_t)fhp, sizeof(nfh)); fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; @@ -2601,7 +2601,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ if (vap->va_mode == (mode_t)VNOVAL) vap->va_mode = 0; - error = VOP_NMKDIR(nd.nl_ncp, &vp, nd.nl_cred, vap); + error = VOP_NMKDIR(&nd.nl_nch, &vp, nd.nl_cred, vap); if (error == 0) { bzero((caddr_t)fhp, sizeof(nfh)); @@ -2702,7 +2702,7 @@ out: if (!error) { vput(vp); vp = NULL; - error = VOP_NRMDIR(nd.nl_ncp, nd.nl_cred); + error = VOP_NRMDIR(&nd.nl_nch, nd.nl_cred); } nlookup_done(&nd); diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index aedd5338d5..3e3c8b5177 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -35,7 +35,7 @@ * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.42 2006/09/03 18:52:30 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.43 2006/10/27 04:56:34 dillon Exp $ */ /* @@ -1433,7 +1433,7 @@ nfs_getattrcache(struct vnode *vp, struct vattr *vaper) * dirp may be set whether an error is returned or not, and must be * released by the caller. * - * On return nd->nl_ncp usually points to the target ncp, which may represent + * On return nd->nl_nch usually points to the target ncp, which may represent * a negative hit. * * NOTE: the caller must call nlookup_done(nd) unconditionally on return @@ -1452,7 +1452,7 @@ nfs_namei(struct nlookupdata *nd, struct ucred *cred, int nameiop, struct mbuf *md; char *fromcp, *tocp, *cp; char *namebuf; - struct namecache *ncp; + struct nchandle nch; struct vnode *dp; int error, rdonly; @@ -1587,12 +1587,10 @@ nfs_namei(struct nlookupdata *nd, struct ucred *cred, int nameiop, * one. If this fails the directory has probably been removed while * the target was chdir'd into it and any further lookup will fail. */ - if ((ncp = cache_fromdvp(dp, cred, 1)) == NULL) { - error = EINVAL; + if ((error = cache_fromdvp(dp, cred, 1, &nch)) != 0) goto out; - } - nlookup_init_raw(nd, namebuf, UIO_SYSSPACE, flags, cred, ncp); - cache_drop(ncp); + nlookup_init_raw(nd, namebuf, UIO_SYSSPACE, flags, cred, &nch); + cache_drop(&nch); /* * Ok, do the lookup. @@ -1601,22 +1599,22 @@ nfs_namei(struct nlookupdata *nd, struct ucred *cred, int nameiop, /* * If no error occured return the requested dvpp and vpp. If - * NLC_CREATE was specified nd->nl_ncp may represent a negative + * NLC_CREATE was specified nd->nl_nch may represent a negative * cache hit in which case we do not attempt to obtain the vp. */ if (error == 0) { - ncp = nd->nl_ncp; if (dvpp) { - if (ncp->nc_parent && - ncp->nc_parent->nc_mount == ncp->nc_mount) { - error = cache_vget(ncp->nc_parent, nd->nl_cred, - LK_EXCLUSIVE, dvpp); + if (nch.ncp->nc_parent) { + nch = nd->nl_nch; + nch.ncp = nch.ncp->nc_parent; + error = cache_vget(&nch, nd->nl_cred, + LK_EXCLUSIVE, dvpp); } else { error = ENXIO; } } - if (vpp && ncp->nc_vp) { - error = cache_vget(ncp, nd->nl_cred, LK_EXCLUSIVE, vpp); + if (vpp && nd->nl_nch.ncp->nc_vp) { + error = cache_vget(&nd->nl_nch, nd->nl_cred, LK_EXCLUSIVE, vpp); } if (error) { if (dvpp && *dvpp) { diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index 11bed1f2f7..93041671d9 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -35,7 +35,7 @@ * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 * $FreeBSD: src/sys/nfs/nfs_syscalls.c,v 1.58.2.1 2000/11/26 02:30:06 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.26 2006/09/05 00:55:50 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_syscalls.c,v 1.27 2006/10/27 04:56:34 dillon Exp $ */ #include @@ -176,7 +176,7 @@ sys_nfssvc(struct nfssvc_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, &vp); + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index c73809da0b..e2187bd46d 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -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.66 2006/09/05 00:55:50 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.67 2006/10/27 04:56:34 dillon Exp $ */ @@ -834,7 +834,7 @@ nfs_nresolve(struct vop_nresolve_args *ap) int32_t t1, t2; cred = ap->a_cred; - ncp = ap->a_ncp; + ncp = ap->a_nch->ncp; KKASSERT(ncp->nc_parent && ncp->nc_parent->nc_vp); dvp = ncp->nc_parent->nc_vp; @@ -867,8 +867,8 @@ nfs_nresolve(struct vop_nresolve_args *ap) nticks = nfsneg_cache_timeout * hz; else nticks = 1; - cache_setvp(ncp, NULL); - cache_settimeout(ncp, nticks); + cache_setvp(ap->a_nch, NULL); + cache_settimeout(ap->a_nch, nticks); } nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); m_freem(mrep); @@ -910,7 +910,7 @@ nfs_nresolve(struct vop_nresolve_args *ap) } else { nfsm_loadattr(nvp, NULL); } - cache_setvp(ncp, nvp); + cache_setvp(ap->a_nch, nvp); m_freem(mrep); nfsmout: vput(dvp); @@ -2371,8 +2371,8 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) u_quad_t fileno; int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; int attrflag, fhsize; - struct namecache *ncp; - struct namecache *dncp; + struct nchandle nch; + struct nchandle dnch; struct nlcomponent nlc; #ifndef nolint @@ -2391,7 +2391,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) * ncp may be unnamed. Note that other unrelated operations may * cause the ncp to be named at any time. */ - dncp = cache_fromdvp(vp, NULL, 0); + cache_fromdvp(vp, NULL, 0, &dnch); bzero(&nlc, sizeof(nlc)); newvp = NULLVP; @@ -2524,14 +2524,14 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) md = mdsav2; dp->nfs_type = IFTODT(VTTOIF(np->n_vattr.va_type)); - if (dncp) { + if (dnch.ncp) { printf("NFS/READDIRPLUS, ENTER %*.*s\n", nlc.nlc_namelen, nlc.nlc_namelen, nlc.nlc_nameptr); - ncp = cache_nlookup(dncp, &nlc); - cache_setunresolved(ncp); - cache_setvp(ncp, newvp); - cache_put(ncp); + nch = cache_nlookup(&dnch, &nlc); + cache_setunresolved(&nch); + cache_setvp(&nch, newvp); + cache_put(&nch); } else { printf("NFS/READDIRPLUS, UNABLE TO ENTER" " %*.*s\n", @@ -2597,8 +2597,8 @@ nfsmout: vput(newvp); newvp = NULLVP; } - if (dncp) - cache_drop(dncp); + if (dnch.ncp) + cache_drop(&dnch); return (error); } diff --git a/sys/vfs/ntfs/ntfs_vfsops.c b/sys/vfs/ntfs/ntfs_vfsops.c index 4fcb25e0ae..b249144c5c 100644 --- a/sys/vfs/ntfs/ntfs_vfsops.c +++ b/sys/vfs/ntfs/ntfs_vfsops.c @@ -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.42 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.43 2006/10/27 04:56:34 dillon Exp $ */ @@ -297,7 +297,7 @@ ntfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) goto error_1; diff --git a/sys/vfs/nullfs/null_vfsops.c b/sys/vfs/nullfs/null_vfsops.c index 5f7db7d8a6..7e646ed4cc 100644 --- a/sys/vfs/nullfs/null_vfsops.c +++ b/sys/vfs/nullfs/null_vfsops.c @@ -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.28 2006/10/10 17:16:48 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vfsops.c,v 1.29 2006/10/27 04:56:34 dillon Exp $ */ /* @@ -97,29 +97,42 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) */ rootvp = NULL; error = nlookup_init(&nd, args.target, UIO_USERSPACE, NLC_FOLLOW); - if (error == 0) - error = nlookup(&nd); - if (error == 0) { - error = cache_vget(nd.nl_ncp, nd.nl_cred, LK_EXCLUSIVE, - &rootvp); - } + if (error) + goto fail1; + error = nlookup(&nd); + if (error) + goto fail2; + error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &rootvp); + if (error) + goto fail2; xmp = (struct null_mount *) kmalloc(sizeof(struct null_mount), M_NULLFSMNT, M_WAITOK); /* XXX */ /* * Save reference to underlying FS - */ - /* + * * As lite stacking enters the scene, the old way of doing this - * -- via the vnode -- is not good enough anymore... + * -- via the vnode -- is not good enough anymore. Use the + * underlying filesystem's namecache handle as our mount point + * root, adjusting the mount to point to us. + * + * NCF_ISMOUNTPT is normally set on the mount point, but we also + * want to set it on the base directory being mounted to prevent + * that directory from being destroyed out from under the nullfs + * mount. */ - xmp->nullm_vfs = nd.nl_ncp->nc_mount; + xmp->nullm_vfs = nd.nl_nch.mount; + mp->mnt_ncmountpt = nd.nl_nch; + cache_changemount(&mp->mnt_ncmountpt, mp); + mp->mnt_ncmountpt.ncp->nc_flag |= NCF_ISMOUNTPT; + cache_unlock(&mp->mnt_ncmountpt); + cache_zero(&nd.nl_nch); nlookup_done(&nd); vfs_add_vnodeops(mp, &null_vnode_vops, &mp->mnt_vn_norm_ops); - vn_unlock(rootvp); + vn_unlock(rootvp); /* leave reference intact */ /* * Keep a held reference to the root vnode. @@ -142,7 +155,16 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) (void)nullfs_statfs(mp, &mp->mnt_stat, cred); NULLFSDEBUG("nullfs_mount: lower %s, alias at %s\n", mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntfromname); + + /* + * So unmount won't complain about namecache refs still existing + */ + mp->mnt_kern_flag |= MNTK_NCALIASED; return (0); +fail2: + nlookup_done(&nd); +fail1: + return (error); } /* diff --git a/sys/vfs/nullfs/null_vnops.c b/sys/vfs/nullfs/null_vnops.c index 020b84de8d..f46b3deeca 100644 --- a/sys/vfs/nullfs/null_vnops.c +++ b/sys/vfs/nullfs/null_vnops.c @@ -38,7 +38,7 @@ * Ancestors: * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/nullfs/null_vnops.c,v 1.38.2.6 2002/07/31 00:32:28 semenu Exp $ - * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.27 2006/07/18 22:22:15 dillon Exp $ + * $DragonFly: src/sys/vfs/nullfs/null_vnops.c,v 1.28 2006/10/27 04:56:34 dillon Exp $ * ...and... * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project * @@ -125,7 +125,7 @@ static int null_nrename(struct vop_nrename_args *ap); static int null_nresolve(struct vop_nresolve_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nresolve_ap(ap); } @@ -133,7 +133,7 @@ null_nresolve(struct vop_nresolve_args *ap) static int null_ncreate(struct vop_ncreate_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_ncreate_ap(ap); } @@ -141,7 +141,7 @@ null_ncreate(struct vop_ncreate_args *ap) static int null_nmkdir(struct vop_nmkdir_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nmkdir_ap(ap); } @@ -149,7 +149,7 @@ null_nmkdir(struct vop_nmkdir_args *ap) static int null_nmknod(struct vop_nmknod_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nmknod_ap(ap); } @@ -157,7 +157,7 @@ null_nmknod(struct vop_nmknod_args *ap) static int null_nlink(struct vop_nlink_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nlink_ap(ap); } @@ -165,7 +165,7 @@ null_nlink(struct vop_nlink_args *ap) static int null_nsymlink(struct vop_nsymlink_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nsymlink_ap(ap); } @@ -173,7 +173,7 @@ null_nsymlink(struct vop_nsymlink_args *ap) static int null_nwhiteout(struct vop_nwhiteout_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nwhiteout_ap(ap); } @@ -181,7 +181,7 @@ null_nwhiteout(struct vop_nwhiteout_args *ap) static int null_nremove(struct vop_nremove_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nremove_ap(ap); } @@ -189,7 +189,7 @@ null_nremove(struct vop_nremove_args *ap) static int null_nrmdir(struct vop_nrmdir_args *ap) { - ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_ncp->nc_mount)->nullm_vfs->mnt_vn_norm_ops; + ap->a_head.a_ops = MOUNTTONULLMOUNT(ap->a_nch->mount)->nullm_vfs->mnt_vn_norm_ops; return vop_nrmdir_ap(ap); } @@ -199,8 +199,8 @@ null_nrename(struct vop_nrename_args *ap) { struct mount *lmp; - lmp = MOUNTTONULLMOUNT(ap->a_fncp->nc_mount)->nullm_vfs; - if (lmp != MOUNTTONULLMOUNT(ap->a_tncp->nc_mount)->nullm_vfs) + lmp = MOUNTTONULLMOUNT(ap->a_fnch->mount)->nullm_vfs; + if (lmp != MOUNTTONULLMOUNT(ap->a_tnch->mount)->nullm_vfs) return (EINVAL); ap->a_head.a_ops = lmp->mnt_vn_norm_ops; diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c index c02ab3aa49..aac1526153 100644 --- a/sys/vfs/udf/udf_vfsops.c +++ b/sys/vfs/udf/udf_vfsops.c @@ -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.23 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.24 2006/10/27 04:56:34 dillon Exp $ */ /* udf_vfsops.c */ @@ -159,7 +159,7 @@ udf_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) return (error); diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c index 4a5f65e142..87068a3274 100644 --- a/sys/vfs/ufs/ffs_vfsops.c +++ b/sys/vfs/ufs/ffs_vfsops.c @@ -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.50 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.51 2006/10/27 04:56:34 dillon Exp $ */ #include "opt_quota.h" @@ -285,7 +285,7 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); nlookup_done(&nd); if (error) goto error_1; diff --git a/sys/vfs/union/union_vfsops.c b/sys/vfs/union/union_vfsops.c index 0571164012..2a91456485 100644 --- a/sys/vfs/union/union_vfsops.c +++ b/sys/vfs/union/union_vfsops.c @@ -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.27 2006/09/19 16:06:17 dillon Exp $ + * $DragonFly: src/sys/vfs/union/union_vfsops.c,v 1.28 2006/10/27 04:56:34 dillon Exp $ */ /* @@ -135,7 +135,7 @@ union_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &upperrootvp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &upperrootvp); nlookup_done(&nd); if (error) goto bad; diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index 6ee24bf222..9d139ad4d4 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -32,7 +32,7 @@ * * @(#)vm_swap.c 8.5 (Berkeley) 2/17/94 * $FreeBSD: src/sys/vm/vm_swap.c,v 1.96.2.2 2001/10/14 18:46:47 iedowse Exp $ - * $DragonFly: src/sys/vm/vm_swap.c,v 1.30 2006/09/10 01:26:41 dillon Exp $ + * $DragonFly: src/sys/vm/vm_swap.c,v 1.31 2006/10/27 04:56:34 dillon Exp $ */ #include "opt_swap.h" @@ -191,7 +191,7 @@ sys_swapon(struct swapon_args *uap) if (error == 0) error = nlookup(&nd); if (error == 0) - error = cache_vref(nd.nl_ncp, nd.nl_cred, &vp); + error = cache_vref(&nd.nl_nch, nd.nl_cred, &vp); nlookup_done(&nd); if (error) return (error); diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index 26b6355592..5bd90a8032 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -33,7 +33,7 @@ * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved. * @(#)fstat.c 8.3 (Berkeley) 5/2/95 * $FreeBSD: src/usr.bin/fstat/fstat.c,v 1.21.2.7 2001/11/21 10:49:37 dwmalone Exp $ - * $DragonFly: src/usr.bin/fstat/fstat.c,v 1.19 2006/09/11 20:24:57 dillon Exp $ + * $DragonFly: src/usr.bin/fstat/fstat.c,v 1.20 2006/10/27 04:56:27 dillon Exp $ */ #define _KERNEL_STRUCTURES @@ -138,10 +138,10 @@ kvm_t *kd; void dofiles(struct kinfo_proc *kp); void dommap(struct kinfo_proc *kp); -void vtrans(struct vnode *vp, struct namecache *ncp, int i, int flag); +void vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag); int ufs_filestat(struct vnode *vp, struct filestat *fsp); int nfs_filestat(struct vnode *vp, struct filestat *fsp); -char *getmnton(struct mount *m, struct namecache_list *ncplist, struct namecache *ncp); +char *getmnton(struct mount *m, struct namecache_list *ncplist, struct nchandle *ncr); void pipetrans(struct pipe *pi, int i, int flag); void socktrans(struct socket *sock, int i); void getinetproto(int number); @@ -323,11 +323,11 @@ dofiles(struct kinfo_proc *kp) * root directory vnode, if one */ if (filed.fd_rdir) - vtrans(filed.fd_rdir, filed.fd_nrdir, RDIR, FREAD); + vtrans(filed.fd_rdir, &filed.fd_nrdir, RDIR, FREAD); /* * current working directory vnode */ - vtrans(filed.fd_cdir, filed.fd_ncdir, CDIR, FREAD); + vtrans(filed.fd_cdir, &filed.fd_ncdir, CDIR, FREAD); /* * ktrace vnode, if one */ @@ -360,7 +360,7 @@ dofiles(struct kinfo_proc *kp) continue; } if (file.f_type == DTYPE_VNODE) { - vtrans((struct vnode *)file.f_data, file.f_ncp, i, + vtrans((struct vnode *)file.f_data, &file.f_nchandle, i, file.f_flag); } else if (file.f_type == DTYPE_SOCKET) { if (checkfile == 0) @@ -376,7 +376,7 @@ dofiles(struct kinfo_proc *kp) #ifdef DTYPE_FIFO else if (file.f_type == DTYPE_FIFO) { if (checkfile == 0) - vtrans((struct vnode *)file.f_data, file.f_ncp, + vtrans((struct vnode *)file.f_data, &file.f_nchandle, i, file.f_flag); } #endif @@ -448,7 +448,7 @@ dommap(struct kinfo_proc *kp) } void -vtrans(struct vnode *vp, struct namecache *ncp, int i, int flag) +vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag) { struct vnode vn; struct filestat fst; @@ -522,7 +522,7 @@ vtrans(struct vnode *vp, struct namecache *ncp, int i, int flag) if (nflg) (void)printf(" %3d,%-9d ", major(fst.fsid), minor(fst.fsid)); else - (void)printf(" %-*s", wflg_mnt, getmnton(vn.v_mount, &vn.v_namecache, ncp)); + (void)printf(" %-*s", wflg_mnt, getmnton(vn.v_mount, &vn.v_namecache, ncr)); if (nflg) (void)sprintf(mode, "%o", fst.mode); else @@ -627,7 +627,7 @@ nfs_filestat(struct vnode *vp, struct filestat *fsp) char * -getmnton(struct mount *m, struct namecache_list *ncplist, struct namecache *ncp) +getmnton(struct mount *m, struct namecache_list *ncplist, struct nchandle *ncr) { static struct mount mount_l; static struct mtab { @@ -636,6 +636,7 @@ getmnton(struct mount *m, struct namecache_list *ncplist, struct namecache *ncp) char mntonname[MNAMELEN]; } *mhead = NULL; struct mtab *mt; + struct namecache *ncp; struct namecache ncp_copy; static char path[1024]; int i; @@ -643,8 +644,10 @@ getmnton(struct mount *m, struct namecache_list *ncplist, struct namecache *ncp) /* * If no ncp is passed try to find one via ncplist. */ - if (ncp == NULL) { + if (ncr == NULL || ncr->ncp == NULL) { ncp = ncplist->tqh_first; + } else { + ncp = ncr->ncp; } /* @@ -658,10 +661,6 @@ getmnton(struct mount *m, struct namecache_list *ncplist, struct namecache *ncp) warnx("can't read ncp at %p", ncp); return (NULL); } - if (ncp_copy.nc_flag & NCF_MOUNTPT) { - ncp = ncp_copy.nc_parent; - continue; - } if (i <= ncp_copy.nc_nlen) break; i -= ncp_copy.nc_nlen; -- 2.41.0