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