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