File:  [DragonFly] / src / sys / sys / namei.h
Revision 1.10: download - view: text, annotated - select for diffs
Tue Mar 16 17:53:51 2004 UTC (10 years, 5 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Separate chroot() into kern_chroot().  Rename change_dir() to checkvp_chdir()
and reorganize the code to avoid doing weird things to the passed vnode's
lock and ref count in deep subroutines (which lead to buggy code).

Fix a bug in chdir()/kern_chdir() (the namei data was not being freed in all
cases), and also fix a bug in symlink() (missing zfree in error case).

Submitted-by: Paul Herman <pherman@frenchfries.net>
Additional-work-by: dillon

    1: /*
    2:  * Copyright (c) 1985, 1989, 1991, 1993
    3:  *	The Regents of the University of California.  All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  * 3. All advertising materials mentioning features or use of this software
   14:  *    must display the following acknowledgement:
   15:  *	This product includes software developed by the University of
   16:  *	California, Berkeley and its contributors.
   17:  * 4. Neither the name of the University nor the names of its contributors
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  *
   21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  *
   33:  *	@(#)namei.h	8.5 (Berkeley) 1/9/95
   34:  * $FreeBSD: src/sys/sys/namei.h,v 1.29.2.2 2001/09/30 21:12:54 luigi Exp $
   35:  * $DragonFly: src/sys/sys/namei.h,v 1.10 2004/03/16 17:53:51 dillon Exp $
   36:  */
   37: 
   38: #ifndef _SYS_NAMEI_H_
   39: #define	_SYS_NAMEI_H_
   40: 
   41: #include <sys/queue.h>
   42: #include <sys/uio.h>
   43: 
   44: #ifdef _KERNEL
   45: #ifndef _SYS_THREAD_H_
   46: #include <sys/thread.h>
   47: #endif
   48: #ifndef _SYS_PROC_H_
   49: #include <sys/proc.h>
   50: #endif
   51: #endif
   52: 
   53: struct componentname {
   54: 	/*
   55: 	 * Arguments to lookup.
   56: 	 */
   57: 	u_long	cn_nameiop;	/* namei operation */
   58: 	u_long	cn_flags;	/* flags to namei */
   59: 	struct	thread *cn_td;	/* process requesting lookup */
   60: 	struct	ucred *cn_cred;	/* credentials */
   61: 	/*
   62: 	 * Shared between lookup and commit routines.
   63: 	 */
   64: 	char	*cn_pnbuf;	/* pathname buffer */
   65: 	char	*cn_nameptr;	/* pointer to looked up name */
   66: 	long	cn_namelen;	/* length of looked up component */
   67: 	long	cn_consume;	/* chars to consume in lookup() */
   68: };
   69: 
   70: /*
   71:  * Encapsulation of namei parameters.
   72:  */
   73: struct nameidata {
   74: 	/*
   75: 	 * Arguments to namei/lookup.
   76: 	 */
   77: 	const	char *ni_dirp;		/* pathname pointer */
   78: 	enum	uio_seg ni_segflg;	/* location of pathname */
   79: 	/*
   80: 	 * Arguments to lookup.
   81: 	 */
   82: 	struct	vnode *ni_startdir;	/* starting directory */
   83: 	struct	vnode *ni_rootdir;	/* logical root directory */
   84: 	struct	vnode *ni_topdir;	/* logical top directory */
   85: 	/*
   86: 	 * Results: returned from/manipulated by lookup
   87: 	 */
   88: 	struct	vnode *ni_vp;		/* vnode of result */
   89: 	struct	vnode *ni_dvp;		/* vnode of intermediate directory */
   90: 	struct  namecache *ni_ncp;	/* namecache of result */
   91: 	struct  namecache *ni_dncp;	/* namecache of intermediate dir */
   92: 	/*
   93: 	 * Shared between namei and lookup/commit routines.
   94: 	 */
   95: 	size_t	ni_pathlen;		/* remaining chars in path incl \0 */
   96: 	char	*ni_next;		/* next location in pathname */
   97: 	u_long	ni_loopcnt;		/* count of symlinks encountered */
   98: 	/*
   99: 	 * Lookup parameters: this structure describes the subset of
  100: 	 * information from the nameidata structure that is passed
  101: 	 * through the VOP interface.
  102: 	 */
  103: 	struct componentname ni_cnd;
  104: };
  105: 
  106: #ifdef _KERNEL
  107: /*
  108:  * namei operations
  109:  */
  110: #define	NAMEI_LOOKUP	0	/* perform name lookup only */
  111: #define	NAMEI_CREATE	1	/* setup for file creation */
  112: #define	NAMEI_DELETE	2	/* setup for file deletion */
  113: #define	NAMEI_RENAME	3	/* setup for file renaming */
  114: #define	NAMEI_OPMASK	3	/* mask for operation */
  115: /*
  116:  * namei operational modifier flags, stored in ni_cnd.flags
  117:  */
  118: #define	CNP_LOCKLEAF	    0x00000004	/* return target vnode locked */
  119: #define	CNP_LOCKPARENT	    0x00000008	/* return parent vnode locked */
  120: #define	CNP_WANTPARENT	    0x00000010	/* return parent vnode unlocked */
  121: #define	CNP_NOCACHE	    0x00000020	/* name must not be left in cache */
  122: #define	CNP_FOLLOW	    0x00000040	/* follow symbolic links */
  123: #define	CNP_NOOBJ	    0x00000080	/* don't create object */
  124: #define	CNP_WANTDNCP	    0x00400000	/* return target namecache refd */
  125: #define	CNP_WANTNCP	    0x00800000	/* return target namecache refd */
  126: #define	CNP_MODMASK	    0x00c000fc	/* mask of operational modifiers */
  127: /*
  128:  * Namei parameter descriptors.
  129:  *
  130:  * SAVENAME may be set by either the callers of namei or by VOP_LOOKUP.
  131:  * If the caller of namei sets the flag (for example execve wants to
  132:  * know the name of the program that is being executed), then it must
  133:  * free the buffer. If VOP_LOOKUP sets the flag, then the buffer must
  134:  * be freed by either the commit routine or the VOP_ABORT routine.
  135:  * SAVESTART is set only by the callers of namei. It implies SAVENAME
  136:  * plus the addition of saving the parent directory that contains the
  137:  * name in ni_startdir. It allows repeated calls to lookup for the
  138:  * name being sought. The caller is responsible for releasing the
  139:  * buffer and for vrele'ing ni_startdir.
  140:  */
  141: #define	CNP_NOCROSSMOUNT    0x00000100 /* do not cross mount points */
  142: #define	CNP_RDONLY	    0x00000200 /* lookup with read-only semantics */
  143: #define	CNP_HASBUF	    0x00000400 /* has allocated pathname buffer */
  144: #define	CNP_SAVENAME	    0x00000800 /* save pathname buffer */
  145: #define	CNP_SAVESTART	    0x00001000 /* save starting directory */
  146: #define CNP_ISDOTDOT	    0x00002000 /* current component name is .. */
  147: #define CNP_MAKEENTRY	    0x00004000 /* entry will be added to name cache */
  148: #define CNP_ISLASTCN	    0x00008000 /* flag last component of pathname */
  149: #define CNP_ISSYMLINK	    0x00010000 /* symlink needs interpretation */
  150: #define	CNP_ISWHITEOUT	    0x00020000 /* found whiteout */
  151: #define	CNP_DOWHITEOUT	    0x00040000 /* do whiteouts */
  152: #define	CNP_WILLBEDIR	    0x00080000 /* will be dir, allow trailing / */
  153: #define	CNP_ISUNICODE	    0x00100000 /* current component name is unicode*/
  154: #define	CNP_PDIRUNLOCK	    0x00200000 /* fs lookup() unlocked parent dir */
  155: 	/* (WANTDNCP)	    0x00400000 */
  156: 	/* (WANTNCP)	    0x00800000 */
  157: #define CNP_PARAMASK	    0x001fff00 /* mask of parameter descriptors */
  158: /*
  159:  * Initialization of an nameidata structure.
  160:  */
  161: 
  162: static __inline void
  163: _NDINIT(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
  164: 	const char *namep, struct thread *td
  165: ) {
  166: 	ndp->ni_cnd.cn_nameiop = op;
  167: 	ndp->ni_cnd.cn_flags = flags;
  168: 	ndp->ni_segflg = segflg;
  169: 	ndp->ni_dirp = namep;
  170: 	ndp->ni_cnd.cn_td = td;
  171: }
  172: 
  173: static __inline void
  174: NDINIT(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
  175: 	const char *namep, struct thread *td
  176: ) {
  177: 	struct proc *p;
  178: 
  179: 	_NDINIT(ndp, op, flags, segflg, namep, td);
  180: 	p = td->td_proc;
  181: 	KKASSERT(p != NULL);
  182: 	ndp->ni_cnd.cn_cred = p->p_ucred;
  183: }
  184: 
  185: static __inline void
  186: NDINIT2(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
  187: 	const char *namep, struct thread *td, struct ucred *cr
  188: ) {
  189: 	_NDINIT(ndp, op, flags, segflg, namep, td);
  190: 	ndp->ni_cnd.cn_cred = cr;
  191: }
  192: 
  193: #define NDF_NO_DVP_RELE		0x00000001
  194: #define NDF_NO_DVP_UNLOCK	0x00000002
  195: #define NDF_NO_DVP_PUT		0x00000003
  196: #define NDF_NO_VP_RELE		0x00000004
  197: #define NDF_NO_VP_UNLOCK	0x00000008
  198: #define NDF_NO_VP_PUT		(NDF_NO_VP_RELE|NDF_NO_VP_UNLOCK)
  199: #define NDF_NO_STARTDIR_RELE	0x00000010
  200: #define NDF_NO_FREE_PNBUF	0x00000020
  201: #define NDF_NO_DNCP_RELE	0x00000040
  202: #define NDF_NO_NCP_RELE		0x00000080
  203: 
  204: #define NDF_ONLY_PNBUF		(~NDF_NO_FREE_PNBUF)
  205: #define NDF_ONLY_PNBUF_AND_NCPS	(~(NDF_NO_FREE_PNBUF|NDF_NO_DNCP_RELE|NDF_NO_NCP_RELE))
  206: 
  207: void NDFREE (struct nameidata *, const uint);
  208: 
  209: int	namei (struct nameidata *ndp);
  210: int	lookup (struct nameidata *ndp);
  211: int	relookup (struct vnode *dvp, struct vnode **vpp,
  212: 	    struct componentname *cnp);
  213: #endif
  214: 
  215: /*
  216:  * Stats on usefulness of namei caches.
  217:  */
  218: struct	nchstats {
  219: 	long	ncs_goodhits;		/* hits that we can really use */
  220: 	long	ncs_neghits;		/* negative hits that we can use */
  221: 	long	ncs_badhits;		/* hits we must drop */
  222: 	long	ncs_falsehits;		/* hits with id mismatch */
  223: 	long	ncs_miss;		/* misses */
  224: 	long	ncs_long;		/* long names that ignore cache */
  225: 	long	ncs_pass2;		/* names found with passes == 2 */
  226: 	long	ncs_2passes;		/* number of times we attempt it */
  227: };
  228: 
  229: extern struct nchstats nchstats;
  230: 
  231: #endif /* !_SYS_NAMEI_H_ */