| 1 | /* $NetBSD: namei.h,v 1.93 2015/04/21 03:19:03 riastradh 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.37 2015/04/21 03:18:21 riastradh 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 seperate cache line. |
| 212 | */ |
| 213 | struct namecache { |
| 214 | LIST_ENTRY(namecache) nc_hash; /* hash chain */ |
| 215 | LIST_ENTRY(namecache) nc_vhash; /* directory hash chain */ |
| 216 | struct vnode *nc_dvp; /* vnode of parent of name */ |
| 217 | struct vnode *nc_vp; /* vnode the name refers to */ |
| 218 | int nc_flags; /* copy of componentname's ISWHITEOUT */ |
| 219 | char nc_nlen; /* length of name */ |
| 220 | char nc_name[NCHNAMLEN]; /* segment name */ |
| 221 | void *nc_gcqueue; /* queue for garbage collection */ |
| 222 | TAILQ_ENTRY(namecache) nc_lru; /* psuedo-lru chain */ |
| 223 | LIST_ENTRY(namecache) nc_dvlist; |
| 224 | LIST_ENTRY(namecache) nc_vlist; |
| 225 | kmutex_t nc_lock; /* lock on this entry */ |
| 226 | int nc_hittime; /* last time scored a hit */ |
| 227 | }; |
| 228 | |
| 229 | #ifdef _KERNEL |
| 230 | #include <sys/pool.h> |
| 231 | |
| 232 | struct mount; |
| 233 | struct cpu_info; |
| 234 | |
| 235 | extern pool_cache_t pnbuf_cache; /* pathname buffer cache */ |
| 236 | |
| 237 | #define PNBUF_GET() ((char *)pool_cache_get(pnbuf_cache, PR_WAITOK)) |
| 238 | #define PNBUF_PUT(pnb) pool_cache_put(pnbuf_cache, (void *)(pnb)) |
| 239 | |
| 240 | /* |
| 241 | * Typesafe flags for namei_simple/nameiat_simple. |
| 242 | * |
| 243 | * This encoding is not optimal but serves the important purpose of |
| 244 | * not being type-compatible with the regular namei flags. |
| 245 | */ |
| 246 | struct namei_simple_flags_type; /* Opaque. */ |
| 247 | typedef const struct namei_simple_flags_type *namei_simple_flags_t; /* Gross. */ |
| 248 | extern const namei_simple_flags_t |
| 249 | NSM_NOFOLLOW_NOEMULROOT, |
| 250 | NSM_NOFOLLOW_TRYEMULROOT, |
| 251 | NSM_FOLLOW_NOEMULROOT, |
| 252 | NSM_FOLLOW_TRYEMULROOT; |
| 253 | |
| 254 | /* |
| 255 | * namei(at)?_simple_* - the simple cases of namei, with no struct |
| 256 | * nameidata involved. |
| 257 | * |
| 258 | * namei_simple_kernel takes a kernel-space path as the first argument. |
| 259 | * namei_simple_user takes a user-space path as the first argument. |
| 260 | * The nameiat_simple_* variants handle relative path using the given |
| 261 | * directory vnode instead of current directory. |
| 262 | * |
| 263 | * A namei call can be converted to namei_simple_* if: |
| 264 | * - the second arg to NDINIT is LOOKUP; |
| 265 | * - it does not need the parent vnode, nd.ni_dvp; |
| 266 | * - the only flags it uses are (NO)FOLLOW and TRYEMULROOT; |
| 267 | * - it does not do anything else gross with the contents of nd. |
| 268 | */ |
| 269 | int namei_simple_kernel(const char *, namei_simple_flags_t, struct vnode **); |
| 270 | int namei_simple_user(const char *, namei_simple_flags_t, struct vnode **); |
| 271 | int nameiat_simple_kernel(struct vnode *, const char *, namei_simple_flags_t, |
| 272 | struct vnode **); |
| 273 | int nameiat_simple_user(struct vnode *, const char *, namei_simple_flags_t, |
| 274 | struct vnode **); |
| 275 | |
| 276 | int namei(struct nameidata *); |
| 277 | uint32_t namei_hash(const char *, const char **); |
| 278 | int lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow); |
| 279 | int lookup_for_nfsd_index(struct nameidata *, struct vnode *); |
| 280 | int relookup(struct vnode *, struct vnode **, struct componentname *, int); |
| 281 | void cache_purge1(struct vnode *, const char *, size_t, int); |
| 282 | #define PURGE_PARENTS 1 |
| 283 | #define PURGE_CHILDREN 2 |
| 284 | #define cache_purge(vp) cache_purge1((vp),NULL,0,PURGE_PARENTS|PURGE_CHILDREN) |
| 285 | int cache_lookup(struct vnode *, const char *, size_t, uint32_t, uint32_t, |
| 286 | int *, struct vnode **); |
| 287 | int cache_lookup_raw(struct vnode *, const char *, size_t, uint32_t, |
| 288 | int *, struct vnode **); |
| 289 | int cache_revlookup(struct vnode *, struct vnode **, char **, char *); |
| 290 | void cache_enter(struct vnode *, struct vnode *, |
| 291 | const char *, size_t, uint32_t); |
| 292 | void nchinit(void); |
| 293 | void nchreinit(void); |
| 294 | void namecache_count_pass2(void); |
| 295 | void namecache_count_2passes(void); |
| 296 | void cache_cpu_init(struct cpu_info *); |
| 297 | void cache_purgevfs(struct mount *); |
| 298 | void namecache_print(struct vnode *, void (*)(const char *, ...) |
| 299 | __printflike(1, 2)); |
| 300 | |
| 301 | #endif |
| 302 | |
| 303 | /* |
| 304 | * Stats on usefulness of namei caches. A couple of structures are |
| 305 | * used for counting, with members having the same names but different |
| 306 | * types. Containerize member names with the preprocessor to avoid |
| 307 | * cut-'n'-paste. A (U) in the comment documents values that are |
| 308 | * incremented unlocked; we may treat these specially. |
| 309 | */ |
| 310 | #define _NAMEI_CACHE_STATS(type) { \ |
| 311 | type ncs_goodhits; /* hits that we can really use (U) */ \ |
| 312 | type ncs_neghits; /* negative hits that we can use */ \ |
| 313 | type ncs_badhits; /* hits we must drop */ \ |
| 314 | type ncs_falsehits; /* hits with id mismatch (U) */ \ |
| 315 | type ncs_miss; /* misses */ \ |
| 316 | type ncs_long; /* long names that ignore cache */ \ |
| 317 | type ncs_pass2; /* names found with passes == 2 (U) */ \ |
| 318 | type ncs_2passes; /* number of times we attempt it (U) */ \ |
| 319 | type ncs_revhits; /* reverse-cache hits */ \ |
| 320 | type ncs_revmiss; /* reverse-cache misses */ \ |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | * Sysctl deals with a uint64_t version of the stats and summary |
| 325 | * totals are kept that way. |
| 326 | */ |
| 327 | struct nchstats _NAMEI_CACHE_STATS(uint64_t); |
| 328 | |
| 329 | /* #endif !_SYS_NAMEI_H_ (generated by gennameih.awk) */ |
| 330 | |
| 331 | /* Definitions match above, but with NAMEI_ prefix */ |
| 332 | #define NAMEI_LOOKUP 0 |
| 333 | #define NAMEI_CREATE 1 |
| 334 | #define NAMEI_DELETE 2 |
| 335 | #define NAMEI_RENAME 3 |
| 336 | #define NAMEI_OPMASK 3 |
| 337 | #define NAMEI_LOCKLEAF 0x00000004 |
| 338 | #define NAMEI_LOCKPARENT 0x00000008 |
| 339 | #define NAMEI_TRYEMULROOT 0x00000010 |
| 340 | #define NAMEI_NOCACHE 0x00000020 |
| 341 | #define NAMEI_FOLLOW 0x00000040 |
| 342 | #define NAMEI_NOFOLLOW 0x00000000 |
| 343 | #define NAMEI_EMULROOTSET 0x00000080 |
| 344 | #define NAMEI_NOCHROOT 0x01000000 |
| 345 | #define NAMEI_MODMASK 0x010000fc |
| 346 | #define NAMEI_NOCROSSMOUNT 0x0000100 |
| 347 | #define NAMEI_RDONLY 0x0000200 |
| 348 | #define NAMEI_ISDOTDOT 0x0002000 |
| 349 | #define NAMEI_MAKEENTRY 0x0004000 |
| 350 | #define NAMEI_ISLASTCN 0x0008000 |
| 351 | #define NAMEI_ISWHITEOUT 0x0020000 |
| 352 | #define NAMEI_DOWHITEOUT 0x0040000 |
| 353 | #define NAMEI_REQUIREDIR 0x0080000 |
| 354 | #define NAMEI_CREATEDIR 0x0200000 |
| 355 | #define NAMEI_PARAMASK 0x02ee300 |
| 356 | |
| 357 | #endif /* !_SYS_NAMEI_H_ */ |
| 358 | |