| 1 | /*	$NetBSD: namei.h,v 1.120 2024/07/01 00:58:43 christos 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.65 2024/07/01 00:58:05 christos 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 | #if defined(_KERNEL) || defined(_MODULE) |
| 49 | #include <sys/kauth.h> |
| 50 | #include <sys/rwlock.h> |
| 51 | |
| 52 | /* |
| 53 | * Abstraction for a single pathname. |
| 54 | * |
| 55 | * This contains both the pathname string and (eventually) all |
| 56 | * metadata that determines how the path is to be interpreted. |
| 57 | * It is an opaque structure; the implementation is in vfs_lookup.c. |
| 58 | * |
| 59 | * To call namei, first set up a pathbuf with pathbuf_create or |
| 60 | * pathbuf_copyin, then do NDINIT(), then call namei, then AFTER THE |
| 61 | * STRUCT NAMEIDATA IS DEAD, call pathbuf_destroy. Don't destroy the |
| 62 | * pathbuf before you've finished using the nameidata, or mysterious |
| 63 | * bad things may happen. |
| 64 | * |
| 65 | * pathbuf_assimilate is like pathbuf_create but assumes ownership of |
| 66 | * the string buffer passed in, which MUST BE of size PATH_MAX and |
| 67 | * have been allocated with PNBUF_GET(). This should only be used when |
| 68 | * absolutely necessary; e.g. nfsd uses it for loading paths from |
| 69 | * mbufs. |
| 70 | */ |
| 71 | struct pathbuf; |
| 72 | |
| 73 | struct pathbuf *pathbuf_create(const char *path); |
| 74 | struct pathbuf *pathbuf_assimilate(char *path); |
| 75 | int pathbuf_copyin(const char *userpath, struct pathbuf **ret); |
| 76 | void pathbuf_destroy(struct pathbuf *); |
| 77 | |
| 78 | /* get a copy of the (current) path string */ |
| 79 | void pathbuf_copystring(const struct pathbuf *, char *buf, size_t maxlen); |
| 80 | |
| 81 | /* hold a reference copy of the original path string */ |
| 82 | const char *pathbuf_stringcopy_get(struct pathbuf *); |
| 83 | void pathbuf_stringcopy_put(struct pathbuf *, const char *); |
| 84 | |
| 85 | // XXX remove this |
| 86 | int pathbuf_maybe_copyin(const char *userpath, enum uio_seg seg, struct pathbuf **ret); |
| 87 | |
| 88 | /* |
| 89 | * Lookup parameters: this structure describes the subset of |
| 90 | * information from the nameidata structure that is passed |
| 91 | * through the VOP interface. |
| 92 | */ |
| 93 | struct componentname { |
| 94 | 	/* |
| 95 | 	 * Arguments to lookup. |
| 96 | 	 */ |
| 97 | 	uint32_t	cn_nameiop;	/* namei operation */ |
| 98 | 	uint32_t	cn_flags;	/* flags to namei */ |
| 99 | 	kauth_cred_t 	cn_cred;	/* credentials */ |
| 100 | 	/* |
| 101 | 	 * Shared between lookup and commit routines. |
| 102 | 	 */ |
| 103 | 	const char 	*cn_nameptr;	/* pointer to looked up name */ |
| 104 | 	size_t		cn_namelen;	/* length of looked up comp */ |
| 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	LOCKSHARED	0x00000100	/* want shared locks if possible */ |
| 163 | #define	NOCHROOT	0x01000000	/* no chroot on abs path lookups */ |
| 164 | #define	NONEXCLHACK	0x02000000	/* open wwith O_CREAT but not O_EXCL */ |
| 165 | #define	MODMASK		0x030001fc	/* mask of operational modifiers */ |
| 166 | /* |
| 167 | * Namei parameter descriptors. |
| 168 | */ |
| 169 | #define	NOCROSSMOUNT	0x0000800	/* do not cross mount points */ |
| 170 | #define	RDONLY		0x0001000	/* lookup with read-only semantics */ |
| 171 | #define	ISDOTDOT	0x0002000	/* current component name is .. */ |
| 172 | #define	MAKEENTRY	0x0004000	/* entry is to be added to name cache */ |
| 173 | #define	ISLASTCN	0x0008000	/* this is last component of pathname */ |
| 174 | #define	WILLBEDIR	0x0010000	/* new files will be dirs */ |
| 175 | #define	ISWHITEOUT	0x0020000	/* found whiteout */ |
| 176 | #define	DOWHITEOUT	0x0040000	/* do whiteouts */ |
| 177 | #define	REQUIREDIR	0x0080000	/* must be a directory */ |
| 178 | #define	CREATEDIR	0x0200000	/* trailing slashes are ok */ |
| 179 | #define	PARAMASK	0x02ff800	/* mask of parameter descriptors */ |
| 180 | |
| 181 | /* |
| 182 | * Initialization of a nameidata structure. |
| 183 | */ |
| 184 | #define NDINIT(ndp, op, flags, pathbuf) { \ |
| 185 | 	(ndp)->ni_cnd.cn_nameiop = op; \ |
| 186 | 	(ndp)->ni_cnd.cn_flags = flags; \ |
| 187 | 	(ndp)->ni_atdir = NULL; \ |
| 188 | 	(ndp)->ni_pathbuf = pathbuf; \ |
| 189 | 	(ndp)->ni_cnd.cn_cred = kauth_cred_get(); \ |
| 190 | } |
| 191 | |
| 192 | /* |
| 193 | * Use this to set the start directory for openat()-type operations. |
| 194 | */ |
| 195 | #define NDAT(ndp, dir) {			\ |
| 196 | 	(ndp)->ni_atdir = (dir);		\ |
| 197 | } |
| 198 | |
| 199 | #endif |
| 200 | |
| 201 | #ifdef __NAMECACHE_PRIVATE |
| 202 | #include <sys/rbtree.h> |
| 203 | |
| 204 | /* |
| 205 | * For simplicity (and economy of storage), names longer than |
| 206 | * a maximum length of NCHNAMLEN are stored in non-pooled storage. |
| 207 | */ |
| 208 | #define	NCHNAMLEN	sizeof(((struct namecache *)NULL)->nc_name) |
| 209 | |
| 210 | /* |
| 211 | * The uintptr_t-sized key value computed for each name consists of name |
| 212 | * length and a hash value. On 32-bit platforms the top NC_NLEN_BITS of |
| 213 | * the 32-bit hash value is lobbed off. |
| 214 | */ |
| 215 | |
| 216 | #define	NC_NLEN_BITS	11 |
| 217 | #define	NC_NLEN_MASK	((1 << NC_NLEN_BITS) - 1) |
| 218 | #define	NC_NLEN(ncp)	((ncp)->nc_key & NC_NLEN_MASK) |
| 219 | |
| 220 | /* |
| 221 | * Namecache entry. |
| 222 | * |
| 223 | * This structure describes the elements in the cache of recent names looked |
| 224 | * up by namei. It's carefully sized to take up 128 bytes on _LP64 and 64 |
| 225 | * bytes on 32-bit machines, to make good use of space and the CPU caches. |
| 226 | * |
| 227 | * Items used during RB tree lookup (nc_tree, nc_key) are clustered at the |
| 228 | * start of the structure to minimise cache misses during lookup. |
| 229 | * |
| 230 | * Field markings and their corresponding locks: |
| 231 | * |
| 232 | * - stable throughout the lifetime of the namecache entry |
| 233 | * d protected by nc_dvp->vi_nc_lock |
| 234 | * v protected by nc_vp->vi_nc_listlock |
| 235 | * l protected by cache_lru_lock |
| 236 | */ |
| 237 | struct namecache { |
| 238 | 	struct	rb_node nc_tree;	/* d red-black tree, must be first */ |
| 239 | 	uintptr_t nc_key;		/* - hashed key value */ |
| 240 | 	TAILQ_ENTRY(namecache) nc_list;	/* v nc_vp's list of cache entries */ |
| 241 | 	TAILQ_ENTRY(namecache) nc_lru;	/* l pseudo-lru chain */ |
| 242 | 	struct	vnode *nc_dvp;		/* - vnode of parent of name */ |
| 243 | 	struct	vnode *nc_vp;		/* - vnode the name refers to */ |
| 244 | 	u_char	nc_lrulist;		/* l LRU list entry is on */ |
| 245 | 	u_char	nc_whiteout;		/* - whiteout indicator */ |
| 246 | #ifdef _LP64 |
| 247 | 	char	nc_name[46];		/* - segment name */ |
| 248 | #else |
| 249 | 	char	nc_name[22];		/* - segment name */ |
| 250 | #endif |
| 251 | }; |
| 252 | #endif /* __NAMECACHE_PRIVATE */ |
| 253 | |
| 254 | #ifdef _KERNEL |
| 255 | #include <sys/kmem.h> |
| 256 | |
| 257 | struct mount; |
| 258 | struct cpu_info; |
| 259 | |
| 260 | #define	PNBUF_GET()	((char *)kmem_alloc(MAXPATHLEN, KM_SLEEP)) |
| 261 | #define	PNBUF_PUT(pnb)	kmem_free((pnb), MAXPATHLEN) |
| 262 | |
| 263 | /* |
| 264 | * Typesafe flags for namei_simple/nameiat_simple. |
| 265 | * |
| 266 | * This encoding is not optimal but serves the important purpose of |
| 267 | * not being type-compatible with the regular namei flags. |
| 268 | */ |
| 269 | struct namei_simple_flags_type; /* Opaque. */ |
| 270 | typedef const struct namei_simple_flags_type *namei_simple_flags_t; /* Gross. */ |
| 271 | extern const namei_simple_flags_t |
| 272 | 	NSM_NOFOLLOW_NOEMULROOT, |
| 273 | 	NSM_NOFOLLOW_TRYEMULROOT, |
| 274 | 	NSM_FOLLOW_NOEMULROOT, |
| 275 | 	NSM_FOLLOW_TRYEMULROOT; |
| 276 | |
| 277 | /* |
| 278 | * namei(at)?_simple_* - the simple cases of namei, with no struct |
| 279 | * nameidata involved. |
| 280 | * |
| 281 | * namei_simple_kernel takes a kernel-space path as the first argument. |
| 282 | * namei_simple_user takes a user-space path as the first argument. |
| 283 | * The nameiat_simple* variants handle relative path using the given |
| 284 | * directory vnode instead of current directory. |
| 285 | * |
| 286 | * A namei call can be converted to namei_simple_* if: |
| 287 | * - the second arg to NDINIT is LOOKUP; |
| 288 | * - it does not need the parent vnode, nd.ni_dvp; |
| 289 | * - the only flags it uses are (NO)FOLLOW and TRYEMULROOT; |
| 290 | * - it does not do anything else gross with the contents of nd. |
| 291 | */ |
| 292 | int namei_simple_kernel(const char *, namei_simple_flags_t, struct vnode **); |
| 293 | int namei_simple_user(const char *, namei_simple_flags_t, struct vnode **); |
| 294 | int nameiat_simple(struct vnode *, struct pathbuf *, namei_simple_flags_t, |
| 295 | struct vnode **); |
| 296 | int nameiat_simple_kernel(struct vnode *, const char *, namei_simple_flags_t, |
| 297 | struct vnode **); |
| 298 | int nameiat_simple_user(struct vnode *, const char *, namei_simple_flags_t, |
| 299 | struct vnode **); |
| 300 | |
| 301 | int	namei(struct nameidata *); |
| 302 | uint32_t namei_hash(const char *, const char **); |
| 303 | int	lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow); |
| 304 | int	lookup_for_nfsd_index(struct nameidata *, struct vnode *); |
| 305 | int	relookup(struct vnode *, struct vnode **, struct componentname *, int); |
| 306 | void	cache_purge1(struct vnode *, const char *, size_t, int); |
| 307 | #define	PURGE_PARENTS	1 |
| 308 | #define	PURGE_CHILDREN	2 |
| 309 | #define	cache_purge(vp)	cache_purge1((vp),NULL,0,PURGE_PARENTS|PURGE_CHILDREN) |
| 310 | bool	cache_lookup(struct vnode *, const char *, size_t, uint32_t, uint32_t, |
| 311 | 			int *, struct vnode **); |
| 312 | bool	cache_lookup_raw(struct vnode *, const char *, size_t, uint32_t, |
| 313 | 			int *, struct vnode **); |
| 314 | bool	cache_lookup_linked(struct vnode *, const char *, size_t, |
| 315 | 			 struct vnode **, krwlock_t **, kauth_cred_t); |
| 316 | int	cache_revlookup(struct vnode *, struct vnode **, char **, char *, |
| 317 | 			bool, accmode_t); |
| 318 | int	cache_diraccess(struct vnode *, int); |
| 319 | void	cache_enter(struct vnode *, struct vnode *, |
| 320 | 			const char *, size_t, uint32_t); |
| 321 | void	cache_enter_id(struct vnode *, mode_t, uid_t, gid_t, bool); |
| 322 | bool	cache_have_id(struct vnode *); |
| 323 | void	cache_vnode_init(struct vnode * ); |
| 324 | void	cache_vnode_fini(struct vnode * ); |
| 325 | void	cache_cpu_init(struct cpu_info *); |
| 326 | void	cache_enter_mount(struct vnode *, struct vnode *); |
| 327 | bool	cache_cross_mount(struct vnode **, krwlock_t **); |
| 328 | bool	cache_lookup_mount(struct vnode *, struct vnode **); |
| 329 | |
| 330 | void	nchinit(void); |
| 331 | void	namecache_count_pass2(void); |
| 332 | void	namecache_count_2passes(void); |
| 333 | void	cache_purgevfs(struct mount *); |
| 334 | void	namecache_print(struct vnode *, void (*)(const char *, ...) |
| 335 | __printflike(1, 2)); |
| 336 | |
| 337 | #endif |
| 338 | |
| 339 | /* |
| 340 | * Stats on usefulness of namei caches. A couple of structures are |
| 341 | * used for counting, with members having the same names but different |
| 342 | * types. Containerize member names with the preprocessor to avoid |
| 343 | * cut-'n'-paste. |
| 344 | */ |
| 345 | #define	_NAMEI_CACHE_STATS(type) {					\ |
| 346 | 	type	ncs_goodhits;	/* hits that we can really use */	\ |
| 347 | 	type	ncs_neghits;	/* negative hits that we can use */	\ |
| 348 | 	type	ncs_badhits;	/* hits we must drop */			\ |
| 349 | 	type	ncs_falsehits;	/* hits with id mismatch */		\ |
| 350 | 	type	ncs_miss;	/* misses */				\ |
| 351 | 	type	ncs_long;	/* long names that ignore cache */	\ |
| 352 | 	type	ncs_pass2;	/* names found with passes == 2 */	\ |
| 353 | 	type	ncs_2passes;	/* number of times we attempt it */	\ |
| 354 | 	type	ncs_revhits;	/* reverse-cache hits */		\ |
| 355 | 	type	ncs_revmiss;	/* reverse-cache misses */		\ |
| 356 | 	type	ncs_denied;	/* access denied */			\ |
| 357 | } |
| 358 | |
| 359 | /* |
| 360 | * Sysctl deals with a uint64_t version of the stats and summary |
| 361 | * totals are kept that way. |
| 362 | */ |
| 363 | struct	nchstats _NAMEI_CACHE_STATS(uint64_t); |
| 364 | |
| 365 | /* #endif !_SYS_NAMEI_H_ (generated by gennameih.awk) */ |
| 366 | |
| 367 | /* Definitions match above, but with NAMEI_ prefix */ |
| 368 | #define NAMEI_LOOKUP	0 |
| 369 | #define NAMEI_CREATE	1 |
| 370 | #define NAMEI_DELETE	2 |
| 371 | #define NAMEI_RENAME	3 |
| 372 | #define NAMEI_OPMASK	3 |
| 373 | #define NAMEI_LOCKLEAF	0x00000004 |
| 374 | #define NAMEI_LOCKPARENT	0x00000008 |
| 375 | #define NAMEI_TRYEMULROOT	0x00000010 |
| 376 | #define NAMEI_NOCACHE	0x00000020 |
| 377 | #define NAMEI_FOLLOW	0x00000040 |
| 378 | #define NAMEI_NOFOLLOW	0x00000000 |
| 379 | #define NAMEI_EMULROOTSET	0x00000080 |
| 380 | #define NAMEI_LOCKSHARED	0x00000100 |
| 381 | #define NAMEI_NOCHROOT	0x01000000 |
| 382 | #define NAMEI_NONEXCLHACK	0x02000000 |
| 383 | #define NAMEI_MODMASK	0x030001fc |
| 384 | #define NAMEI_NOCROSSMOUNT	0x0000800 |
| 385 | #define NAMEI_RDONLY	0x0001000 |
| 386 | #define NAMEI_ISDOTDOT	0x0002000 |
| 387 | #define NAMEI_MAKEENTRY	0x0004000 |
| 388 | #define NAMEI_ISLASTCN	0x0008000 |
| 389 | #define NAMEI_WILLBEDIR	0x0010000 |
| 390 | #define NAMEI_ISWHITEOUT	0x0020000 |
| 391 | #define NAMEI_DOWHITEOUT	0x0040000 |
| 392 | #define NAMEI_REQUIREDIR	0x0080000 |
| 393 | #define NAMEI_CREATEDIR	0x0200000 |
| 394 | #define NAMEI_PARAMASK	0x02ff800 |
| 395 | |
| 396 | #endif /* !_SYS_NAMEI_H_ */ |