| 1 | /*	$NetBSD: namei.h,v 1.98 2019/06/03 06:05:39 msaitoh Exp $	*/ | 
| 2 |  | 
| 3 |  | 
| 4 | /* | 
| 5 |  * WARNING: GENERATED FILE.  DO NOT EDIT | 
| 6 |  * (edit namei.src and run make namei in src/sys/sys) | 
| 7 |  *   by:   NetBSD: gennameih.awk,v 1.5 2009/12/23 14:17:19 pooka Exp  | 
| 8 |  *   from: NetBSD: namei.src,v 1.42 2019/06/03 06:04:21 msaitoh Exp  | 
| 9 |  */ | 
| 10 |  | 
| 11 | /* | 
| 12 |  * Copyright (c) 1985, 1989, 1991, 1993 | 
| 13 |  *	The Regents of the University of California.  All rights reserved. | 
| 14 |  * | 
| 15 |  * Redistribution and use in source and binary forms, with or without | 
| 16 |  * modification, are permitted provided that the following conditions | 
| 17 |  * are met: | 
| 18 |  * 1. Redistributions of source code must retain the above copyright | 
| 19 |  *    notice, this list of conditions and the following disclaimer. | 
| 20 |  * 2. Redistributions in binary form must reproduce the above copyright | 
| 21 |  *    notice, this list of conditions and the following disclaimer in the | 
| 22 |  *    documentation and/or other materials provided with the distribution. | 
| 23 |  * 3. Neither the name of the University nor the names of its contributors | 
| 24 |  *    may be used to endorse or promote products derived from this software | 
| 25 |  *    without specific prior written permission. | 
| 26 |  * | 
| 27 |  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 
| 28 |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 29 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
| 30 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
| 31 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
| 32 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
| 33 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
| 34 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
| 35 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
| 36 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
| 37 |  * SUCH DAMAGE. | 
| 38 |  * | 
| 39 |  *	@(#)namei.h	8.5 (Berkeley) 8/20/94 | 
| 40 |  */ | 
| 41 |  | 
| 42 | #ifndef _SYS_NAMEI_H_ | 
| 43 | #define	_SYS_NAMEI_H_ | 
| 44 |  | 
| 45 | #include <sys/queue.h> | 
| 46 | #include <sys/mutex.h> | 
| 47 |  | 
| 48 | #ifdef _KERNEL | 
| 49 | #include <sys/kauth.h> | 
| 50 |  | 
| 51 | /* | 
| 52 |  * Abstraction for a single pathname. | 
| 53 |  * | 
| 54 |  * This contains both the pathname string and (eventually) all | 
| 55 |  * metadata that determines how the path is to be interpreted. | 
| 56 |  * It is an opaque structure; the implementation is in vfs_lookup.c. | 
| 57 |  * | 
| 58 |  * To call namei, first set up a pathbuf with pathbuf_create or | 
| 59 |  * pathbuf_copyin, then do NDINIT(), then call namei, then AFTER THE | 
| 60 |  * STRUCT NAMEIDATA IS DEAD, call pathbuf_destroy. Don't destroy the | 
| 61 |  * pathbuf before you've finished using the nameidata, or mysterious | 
| 62 |  * bad things may happen. | 
| 63 |  * | 
| 64 |  * pathbuf_assimilate is like pathbuf_create but assumes ownership of | 
| 65 |  * the string buffer passed in, which MUST BE of size PATH_MAX and | 
| 66 |  * have been allocated with PNBUF_GET(). This should only be used when | 
| 67 |  * absolutely necessary; e.g. nfsd uses it for loading paths from | 
| 68 |  * mbufs. | 
| 69 |  */ | 
| 70 | struct pathbuf; | 
| 71 |  | 
| 72 | struct pathbuf *pathbuf_create(const char *path); | 
| 73 | struct pathbuf *pathbuf_assimilate(char *path); | 
| 74 | int pathbuf_copyin(const char *userpath, struct pathbuf **ret); | 
| 75 | void pathbuf_destroy(struct pathbuf *); | 
| 76 |  | 
| 77 | /* get a copy of the (current) path string */ | 
| 78 | void pathbuf_copystring(const struct pathbuf *, char *buf, size_t maxlen); | 
| 79 |  | 
| 80 | /* hold a reference copy of the original path string */ | 
| 81 | const char *pathbuf_stringcopy_get(struct pathbuf *); | 
| 82 | void pathbuf_stringcopy_put(struct pathbuf *, const char *); | 
| 83 |  | 
| 84 | // XXX remove this | 
| 85 | int pathbuf_maybe_copyin(const char *userpath, enum uio_seg seg, struct pathbuf **ret); | 
| 86 |  | 
| 87 | /* | 
| 88 |  * Lookup parameters: this structure describes the subset of | 
| 89 |  * information from the nameidata structure that is passed | 
| 90 |  * through the VOP interface. | 
| 91 |  */ | 
| 92 | struct componentname { | 
| 93 | 	/* | 
| 94 | 	 * Arguments to lookup. | 
| 95 | 	 */ | 
| 96 | 	uint32_t	cn_nameiop;	/* namei operation */ | 
| 97 | 	uint32_t	cn_flags;	/* flags to namei */ | 
| 98 | 	kauth_cred_t 	cn_cred;	/* credentials */ | 
| 99 | 	/* | 
| 100 | 	 * Shared between lookup and commit routines. | 
| 101 | 	 */ | 
| 102 | 	const char 	*cn_nameptr;	/* pointer to looked up name */ | 
| 103 | 	size_t		cn_namelen;	/* length of looked up comp */ | 
| 104 | 	size_t		cn_consume;	/* chars to consume in lookup */ | 
| 105 | }; | 
| 106 |  | 
| 107 | /* | 
| 108 |  * Encapsulation of namei parameters. | 
| 109 |  */ | 
| 110 | struct nameidata { | 
| 111 | 	/* | 
| 112 | 	 * Arguments to namei/lookup. | 
| 113 | 	 */ | 
| 114 | 	struct vnode *ni_atdir;		/* startup dir, cwd if null */ | 
| 115 | 	struct pathbuf *ni_pathbuf;	/* pathname container */ | 
| 116 | 	char *ni_pnbuf;			/* extra pathname buffer ref (XXX) */ | 
| 117 | 	/* | 
| 118 | 	 * Arguments to lookup. | 
| 119 | 	 */ | 
| 120 | 	struct	vnode *ni_rootdir;	/* logical root directory */ | 
| 121 | 	struct	vnode *ni_erootdir;	/* emulation root directory */ | 
| 122 | 	/* | 
| 123 | 	 * Results: returned from/manipulated by lookup | 
| 124 | 	 */ | 
| 125 | 	struct	vnode *ni_vp;		/* vnode of result */ | 
| 126 | 	struct	vnode *ni_dvp;		/* vnode of intermediate directory */ | 
| 127 | 	/* | 
| 128 | 	 * Shared between namei and lookup/commit routines. | 
| 129 | 	 */ | 
| 130 | 	size_t		ni_pathlen;	/* remaining chars in path */ | 
| 131 | 	const char	*ni_next;	/* next location in pathname */ | 
| 132 | 	unsigned int	ni_loopcnt;	/* count of symlinks encountered */ | 
| 133 | 	/* | 
| 134 | 	 * Lookup parameters: this structure describes the subset of | 
| 135 | 	 * information from the nameidata structure that is passed | 
| 136 | 	 * through the VOP interface. | 
| 137 | 	 */ | 
| 138 | 	struct componentname ni_cnd; | 
| 139 | }; | 
| 140 |  | 
| 141 | /* | 
| 142 |  * namei operations | 
| 143 |  */ | 
| 144 | #define	LOOKUP		0	/* perform name lookup only */ | 
| 145 | #define	CREATE		1	/* setup for file creation */ | 
| 146 | #define	DELETE		2	/* setup for file deletion */ | 
| 147 | #define	RENAME		3	/* setup for file renaming */ | 
| 148 | #define	OPMASK		3	/* mask for operation */ | 
| 149 | /* | 
| 150 |  * namei operational modifier flags, stored in ni_cnd.cn_flags | 
| 151 |  */ | 
| 152 | #define	LOCKLEAF	0x00000004	/* lock inode on return */ | 
| 153 | #define	LOCKPARENT	0x00000008	/* want parent vnode returned locked */ | 
| 154 | #define	TRYEMULROOT	0x00000010	/* try relative to emulation root | 
| 155 | 					   first */ | 
| 156 | #define	NOCACHE		0x00000020	/* name must not be left in cache */ | 
| 157 | #define	FOLLOW		0x00000040	/* follow symbolic links */ | 
| 158 | #define	NOFOLLOW	0x00000000	/* do not follow symbolic links | 
| 159 | 					   (pseudo) */ | 
| 160 | #define	EMULROOTSET	0x00000080	/* emulation root already | 
| 161 | 					   in ni_erootdir */ | 
| 162 | #define	NOCHROOT	0x01000000	/* no chroot on abs path lookups */ | 
| 163 | #define	MODMASK		0x010000fc	/* mask of operational modifiers */ | 
| 164 | /* | 
| 165 |  * Namei parameter descriptors. | 
| 166 |  */ | 
| 167 | #define	NOCROSSMOUNT	0x0000100	/* do not cross mount points */ | 
| 168 | #define	RDONLY		0x0000200	/* lookup with read-only semantics */ | 
| 169 | #define	ISDOTDOT	0x0002000	/* current component name is .. */ | 
| 170 | #define	MAKEENTRY	0x0004000	/* entry is to be added to name cache */ | 
| 171 | #define	ISLASTCN	0x0008000	/* this is last component of pathname */ | 
| 172 | #define	ISWHITEOUT	0x0020000	/* found whiteout */ | 
| 173 | #define	DOWHITEOUT	0x0040000	/* do whiteouts */ | 
| 174 | #define	REQUIREDIR	0x0080000	/* must be a directory */ | 
| 175 | #define	CREATEDIR	0x0200000	/* trailing slashes are ok */ | 
| 176 | #define	PARAMASK	0x02ee300	/* mask of parameter descriptors */ | 
| 177 |  | 
| 178 | /* | 
| 179 |  * Initialization of a nameidata structure. | 
| 180 |  */ | 
| 181 | #define NDINIT(ndp, op, flags, pathbuf) { \ | 
| 182 | 	(ndp)->ni_cnd.cn_nameiop = op; \ | 
| 183 | 	(ndp)->ni_cnd.cn_flags = flags; \ | 
| 184 | 	(ndp)->ni_atdir = NULL; \ | 
| 185 | 	(ndp)->ni_pathbuf = pathbuf; \ | 
| 186 | 	(ndp)->ni_cnd.cn_cred = kauth_cred_get(); \ | 
| 187 | } | 
| 188 |  | 
| 189 | /* | 
| 190 |  * Use this to set the start directory for openat()-type operations. | 
| 191 |  */ | 
| 192 | #define NDAT(ndp, dir) {			\ | 
| 193 | 	(ndp)->ni_atdir = (dir);		\ | 
| 194 | } | 
| 195 |  | 
| 196 | #endif | 
| 197 |  | 
| 198 | /* | 
| 199 |  * This structure describes the elements in the cache of recent | 
| 200 |  * names looked up by namei. NCHNAMLEN is sized to make structure | 
| 201 |  * size a power of two to optimize allocations.  Minimum reasonable | 
| 202 |  * size is 15. | 
| 203 |  */ | 
| 204 |  | 
| 205 | #define	NCHNAMLEN	31	/* maximum name segment length we bother with */ | 
| 206 |  | 
| 207 | /* | 
| 208 |  * Namecache entry.  This structure is arranged so that frequently | 
| 209 |  * accessed and mostly read-only data is toward the front, with | 
| 210 |  * infrequently accessed data and the lock towards the rear.  The | 
| 211 |  * lock is then more likely to be in a separate cache line. | 
| 212 |  * | 
| 213 |  * Locking rules: | 
| 214 |  * | 
| 215 |  *      -       stable after initialization | 
| 216 |  *      L       namecache_lock | 
| 217 |  *      C       struct nchcpu::cpu_lock | 
| 218 |  *      L/C     insert needs L, read needs L or any C, | 
| 219 |  *              must hold L and all C after (or during) delete before free | 
| 220 |  *      N       struct namecache::nc_lock | 
| 221 |  */ | 
| 222 | struct namecache { | 
| 223 | 	LIST_ENTRY(namecache) nc_hash;	/* L/C hash chain */ | 
| 224 | 	LIST_ENTRY(namecache) nc_vhash;	/* L directory hash chain */ | 
| 225 | 	struct	vnode *nc_dvp;		/* N vnode of parent of name */ | 
| 226 | 	struct	vnode *nc_vp;		/* N vnode the name refers to */ | 
| 227 | 	int	nc_flags;		/* - copy of componentname ISWHITEOUT */ | 
| 228 | 	char	nc_nlen;		/* - length of name */ | 
| 229 | 	char	nc_name[NCHNAMLEN];	/* - segment name */ | 
| 230 | 	void	*nc_gcqueue;		/* N queue for garbage collection */ | 
| 231 | 	TAILQ_ENTRY(namecache) nc_lru;	/* L psuedo-lru chain */ | 
| 232 | 	LIST_ENTRY(namecache) nc_dvlist;/* L dvp's list of cache entries */ | 
| 233 | 	LIST_ENTRY(namecache) nc_vlist; /* L vp's list of cache entries */ | 
| 234 | 	kmutex_t nc_lock;		/*   lock on this entry */ | 
| 235 | 	int	nc_hittime;		/* N last time scored a hit */ | 
| 236 | }; | 
| 237 |  | 
| 238 | #ifdef _KERNEL | 
| 239 | #include <sys/pool.h> | 
| 240 |  | 
| 241 | struct mount; | 
| 242 | struct cpu_info; | 
| 243 |  | 
| 244 | extern pool_cache_t pnbuf_cache;	/* pathname buffer cache */ | 
| 245 |  | 
| 246 | #define	PNBUF_GET()	((char *)pool_cache_get(pnbuf_cache, PR_WAITOK)) | 
| 247 | #define	PNBUF_PUT(pnb)	pool_cache_put(pnbuf_cache, (void *)(pnb)) | 
| 248 |  | 
| 249 | /* | 
| 250 |  * Typesafe flags for namei_simple/nameiat_simple. | 
| 251 |  * | 
| 252 |  * This encoding is not optimal but serves the important purpose of | 
| 253 |  * not being type-compatible with the regular namei flags. | 
| 254 |  */ | 
| 255 | struct namei_simple_flags_type; /* Opaque. */ | 
| 256 | typedef const struct namei_simple_flags_type *namei_simple_flags_t; /* Gross. */ | 
| 257 | extern const namei_simple_flags_t | 
| 258 | 	NSM_NOFOLLOW_NOEMULROOT, | 
| 259 | 	NSM_NOFOLLOW_TRYEMULROOT, | 
| 260 | 	NSM_FOLLOW_NOEMULROOT, | 
| 261 | 	NSM_FOLLOW_TRYEMULROOT; | 
| 262 |  | 
| 263 | /* | 
| 264 |  * namei(at)?_simple_* - the simple cases of namei, with no struct | 
| 265 |  *                       nameidata involved. | 
| 266 |  * | 
| 267 |  * namei_simple_kernel takes a kernel-space path as the first argument. | 
| 268 |  * namei_simple_user takes a user-space path as the first argument. | 
| 269 |  * The nameiat_simple_* variants handle relative path using the given  | 
| 270 |  * directory vnode instead of current directory. | 
| 271 |  * | 
| 272 |  * A namei call can be converted to namei_simple_* if: | 
| 273 |  *    - the second arg to NDINIT is LOOKUP; | 
| 274 |  *    - it does not need the parent vnode, nd.ni_dvp; | 
| 275 |  *    - the only flags it uses are (NO)FOLLOW and TRYEMULROOT; | 
| 276 |  *    - it does not do anything else gross with the contents of nd. | 
| 277 |  */ | 
| 278 | int namei_simple_kernel(const char *, namei_simple_flags_t, struct vnode **); | 
| 279 | int namei_simple_user(const char *, namei_simple_flags_t, struct vnode **); | 
| 280 | int nameiat_simple_kernel(struct vnode *, const char *, namei_simple_flags_t, | 
| 281 |     struct vnode **); | 
| 282 | int nameiat_simple_user(struct vnode *, const char *, namei_simple_flags_t,  | 
| 283 |     struct vnode **); | 
| 284 |  | 
| 285 | int	namei(struct nameidata *); | 
| 286 | uint32_t namei_hash(const char *, const char **); | 
| 287 | int	lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow); | 
| 288 | int	lookup_for_nfsd_index(struct nameidata *, struct vnode *); | 
| 289 | int	relookup(struct vnode *, struct vnode **, struct componentname *, int); | 
| 290 | void	cache_purge1(struct vnode *, const char *, size_t, int); | 
| 291 | #define	PURGE_PARENTS	1 | 
| 292 | #define	PURGE_CHILDREN	2 | 
| 293 | #define	cache_purge(vp)	cache_purge1((vp),NULL,0,PURGE_PARENTS|PURGE_CHILDREN) | 
| 294 | bool	cache_lookup(struct vnode *, const char *, size_t, uint32_t, uint32_t, | 
| 295 | 			int *, struct vnode **); | 
| 296 | bool	cache_lookup_raw(struct vnode *, const char *, size_t, uint32_t, | 
| 297 | 			int *, struct vnode **); | 
| 298 | int	cache_revlookup(struct vnode *, struct vnode **, char **, char *); | 
| 299 | void	cache_enter(struct vnode *, struct vnode *, | 
| 300 | 			const char *, size_t, uint32_t); | 
| 301 | void	nchinit(void); | 
| 302 | void	nchreinit(void); | 
| 303 | void	namecache_count_pass2(void); | 
| 304 | void	namecache_count_2passes(void); | 
| 305 | void	cache_cpu_init(struct cpu_info *); | 
| 306 | void	cache_purgevfs(struct mount *); | 
| 307 | void	namecache_print(struct vnode *, void (*)(const char *, ...) | 
| 308 |     __printflike(1, 2)); | 
| 309 |  | 
| 310 | #endif | 
| 311 |  | 
| 312 | /* | 
| 313 |  * Stats on usefulness of namei caches.  A couple of structures are | 
| 314 |  * used for counting, with members having the same names but different | 
| 315 |  * types.  Containerize member names with the preprocessor to avoid | 
| 316 |  * cut-'n'-paste.  A (U) in the comment documents values that are | 
| 317 |  * incremented unlocked; we may treat these specially. | 
| 318 |  */ | 
| 319 | #define	_NAMEI_CACHE_STATS(type) {					\ | 
| 320 | 	type	ncs_goodhits;	/* hits that we can really use (U) */	\ | 
| 321 | 	type	ncs_neghits;	/* negative hits that we can use */	\ | 
| 322 | 	type	ncs_badhits;	/* hits we must drop */			\ | 
| 323 | 	type	ncs_falsehits;	/* hits with id mismatch (U) */		\ | 
| 324 | 	type	ncs_miss;	/* misses */				\ | 
| 325 | 	type	ncs_long;	/* long names that ignore cache */	\ | 
| 326 | 	type	ncs_pass2;	/* names found with passes == 2 (U) */	\ | 
| 327 | 	type	ncs_2passes;	/* number of times we attempt it (U) */	\ | 
| 328 | 	type	ncs_revhits;	/* reverse-cache hits */		\ | 
| 329 | 	type	ncs_revmiss;	/* reverse-cache misses */		\ | 
| 330 | } | 
| 331 |  | 
| 332 | /* | 
| 333 |  * Sysctl deals with a uint64_t version of the stats and summary | 
| 334 |  * totals are kept that way. | 
| 335 |  */ | 
| 336 | struct	nchstats _NAMEI_CACHE_STATS(uint64_t); | 
| 337 |  | 
| 338 | /* #endif !_SYS_NAMEI_H_ (generated by gennameih.awk) */ | 
| 339 |  | 
| 340 | /* Definitions match above, but with NAMEI_ prefix */ | 
| 341 | #define NAMEI_LOOKUP	0 | 
| 342 | #define NAMEI_CREATE	1 | 
| 343 | #define NAMEI_DELETE	2 | 
| 344 | #define NAMEI_RENAME	3 | 
| 345 | #define NAMEI_OPMASK	3 | 
| 346 | #define NAMEI_LOCKLEAF	0x00000004 | 
| 347 | #define NAMEI_LOCKPARENT	0x00000008 | 
| 348 | #define NAMEI_TRYEMULROOT	0x00000010 | 
| 349 | #define NAMEI_NOCACHE	0x00000020 | 
| 350 | #define NAMEI_FOLLOW	0x00000040 | 
| 351 | #define NAMEI_NOFOLLOW	0x00000000 | 
| 352 | #define NAMEI_EMULROOTSET	0x00000080 | 
| 353 | #define NAMEI_NOCHROOT	0x01000000 | 
| 354 | #define NAMEI_MODMASK	0x010000fc | 
| 355 | #define NAMEI_NOCROSSMOUNT	0x0000100 | 
| 356 | #define NAMEI_RDONLY	0x0000200 | 
| 357 | #define NAMEI_ISDOTDOT	0x0002000 | 
| 358 | #define NAMEI_MAKEENTRY	0x0004000 | 
| 359 | #define NAMEI_ISLASTCN	0x0008000 | 
| 360 | #define NAMEI_ISWHITEOUT	0x0020000 | 
| 361 | #define NAMEI_DOWHITEOUT	0x0040000 | 
| 362 | #define NAMEI_REQUIREDIR	0x0080000 | 
| 363 | #define NAMEI_CREATEDIR	0x0200000 | 
| 364 | #define NAMEI_PARAMASK	0x02ee300 | 
| 365 |  | 
| 366 | #endif /* !_SYS_NAMEI_H_ */ | 
| 367 |  |