xref: /netbsd/sys/sys/namei.src (revision 6550d01e)
1/*	$NetBSD: namei.src,v 1.22 2011/01/07 11:25:10 pooka Exp $	*/
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>
38#include <sys/mutex.h>
39
40#ifdef _KERNEL
41#include <sys/kauth.h>
42
43/*
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.
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.
61 */
62struct pathbuf;
63
64struct pathbuf *pathbuf_create(const char *path);
65struct pathbuf *pathbuf_assimilate(char *path);
66int pathbuf_copyin(const char *userpath, struct pathbuf **ret);
67void pathbuf_destroy(struct pathbuf *);
68
69/* get a copy of the (current) path string */
70void pathbuf_copystring(const struct pathbuf *, char *buf, size_t maxlen);
71
72/* hold a reference copy of the original path string */
73const char *pathbuf_stringcopy_get(struct pathbuf *);
74void pathbuf_stringcopy_put(struct pathbuf *, const char *);
75
76// XXX remove this
77int pathbuf_maybe_copyin(const char *userpath, enum uio_seg seg, struct pathbuf **ret);
78
79/*
80 * Encapsulation of namei parameters.
81 */
82struct nameidata {
83	/*
84	 * Arguments to namei/lookup.
85	 */
86	struct pathbuf *ni_pathbuf;	/* pathname container */
87	char *ni_pnbuf;			/* extra pathname buffer ref (XXX) */
88	/*
89	 * Arguments to lookup.
90	 */
91	struct	vnode *ni_rootdir;	/* logical root directory */
92	struct	vnode *ni_erootdir;	/* emulation root directory */
93	/*
94	 * Results: returned from/manipulated by lookup
95	 */
96	struct	vnode *ni_vp;		/* vnode of result */
97	struct	vnode *ni_dvp;		/* vnode of intermediate directory */
98	/*
99	 * Shared between namei and lookup/commit routines.
100	 */
101	size_t		ni_pathlen;	/* remaining chars in path */
102	const char	*ni_next;	/* next location in pathname */
103	unsigned int	ni_loopcnt;	/* count of symlinks encountered */
104	/*
105	 * Lookup parameters: this structure describes the subset of
106	 * information from the nameidata structure that is passed
107	 * through the VOP interface.
108	 */
109	struct componentname {
110		/*
111		 * Arguments to lookup.
112		 */
113		uint32_t	cn_nameiop;	/* namei operation */
114		uint32_t	cn_flags;	/* flags to namei */
115		kauth_cred_t 	cn_cred;	/* credentials */
116		/*
117		 * Shared between lookup and commit routines.
118		 */
119		const char 	*cn_nameptr;	/* pointer to looked up name */
120		size_t		cn_namelen;	/* length of looked up comp */
121		u_long		cn_hash;	/* hash val of looked up name */
122		size_t		cn_consume;	/* chars to consume in lookup */
123	} ni_cnd;
124};
125
126/*
127 * namei operations
128 */
129NAMEIFL	LOOKUP		0	/* perform name lookup only */
130NAMEIFL	CREATE		1	/* setup for file creation */
131NAMEIFL	DELETE		2	/* setup for file deletion */
132NAMEIFL	RENAME		3	/* setup for file renaming */
133NAMEIFL	OPMASK		3	/* mask for operation */
134/*
135 * namei operational modifier flags, stored in ni_cnd.cn_flags
136 */
137NAMEIFL	LOCKLEAF	0x00000004	/* lock inode on return */
138NAMEIFL	LOCKPARENT	0x00000008	/* want parent vnode returned locked */
139NAMEIFL	TRYEMULROOT	0x00000010	/* try relative to emulation root
140					   first */
141NAMEIFL	NOCACHE		0x00000020	/* name must not be left in cache */
142NAMEIFL	FOLLOW		0x00000040	/* follow symbolic links */
143NAMEIFL	NOFOLLOW	0x00000000	/* do not follow symbolic links
144					   (pseudo) */
145NAMEIFL	EMULROOTSET	0x00000080	/* emulation root already
146					   in ni_erootdir */
147NAMEIFL	NOCHROOT	0x01000000	/* no chroot on abs path lookups */
148NAMEIFL	MODMASK		0x010000fc	/* mask of operational modifiers */
149/*
150 * Namei parameter descriptors.
151 */
152NAMEIFL	NOCROSSMOUNT	0x0000100	/* do not cross mount points */
153NAMEIFL	RDONLY		0x0000200	/* lookup with read-only semantics */
154NAMEIFL	ISDOTDOT	0x0002000	/* current component name is .. */
155NAMEIFL	MAKEENTRY	0x0004000	/* entry is to be added to name cache */
156NAMEIFL	ISLASTCN	0x0008000	/* this is last component of pathname */
157NAMEIFL	ISSYMLINK	0x0010000	/* symlink needs interpretation */
158NAMEIFL	ISWHITEOUT	0x0020000	/* found whiteout */
159NAMEIFL	DOWHITEOUT	0x0040000	/* do whiteouts */
160NAMEIFL	REQUIREDIR	0x0080000	/* must be a directory */
161NAMEIFL	CREATEDIR	0x0200000	/* trailing slashes are ok */
162NAMEIFL	INRENAME	0x0400000	/* operation is a part of ``rename'' */
163NAMEIFL	INRELOOKUP	0x0800000	/* set while inside relookup() */
164NAMEIFL	PARAMASK	0x0efe300	/* mask of parameter descriptors */
165
166/*
167 * Initialization of an nameidata structure.
168 */
169#define NDINIT(ndp, op, flags, pathbuf) { \
170	(ndp)->ni_cnd.cn_nameiop = op; \
171	(ndp)->ni_cnd.cn_flags = flags; \
172	(ndp)->ni_pathbuf = pathbuf; \
173	(ndp)->ni_cnd.cn_cred = kauth_cred_get(); \
174}
175#endif
176
177/*
178 * This structure describes the elements in the cache of recent
179 * names looked up by namei. NCHNAMLEN is sized to make structure
180 * size a power of two to optimize malloc's. Minimum reasonable
181 * size is 15.
182 */
183
184#define	NCHNAMLEN	31	/* maximum name segment length we bother with */
185
186/*
187 * Namecache entry.  This structure is arranged so that frequently
188 * accessed and mostly read-only data is toward the front, with
189 * infrequently accessed data and the lock towards the rear.  The
190 * lock is then more likely to be in a seperate cache line.
191 */
192struct	namecache {
193	LIST_ENTRY(namecache) nc_hash;	/* hash chain */
194	LIST_ENTRY(namecache) nc_vhash;	/* directory hash chain */
195	struct	vnode *nc_dvp;		/* vnode of parent of name */
196	struct	vnode *nc_vp;		/* vnode the name refers to */
197	int	nc_flags;		/* copy of componentname's ISWHITEOUT */
198	char	nc_nlen;		/* length of name */
199	char	nc_name[NCHNAMLEN];	/* segment name */
200	void	*nc_gcqueue;		/* queue for garbage collection */
201	TAILQ_ENTRY(namecache) nc_lru;	/* psuedo-lru chain */
202	LIST_ENTRY(namecache) nc_dvlist;
203	LIST_ENTRY(namecache) nc_vlist;
204	kmutex_t nc_lock;		/* lock on this entry */
205	int	nc_hittime;		/* last time scored a hit */
206};
207
208#ifdef _KERNEL
209#include <sys/mallocvar.h>
210#include <sys/pool.h>
211
212struct mount;
213struct cpu_info;
214
215extern pool_cache_t pnbuf_cache;	/* pathname buffer cache */
216
217#define	PNBUF_GET()	pool_cache_get(pnbuf_cache, PR_WAITOK)
218#define	PNBUF_PUT(pnb)	pool_cache_put(pnbuf_cache, (pnb))
219
220/*
221 * Typesafe flags for namei_simple.
222 *
223 * This encoding is not optimal but serves the important purpose of
224 * not being type-compatible with the regular namei flags.
225 */
226struct namei_simple_flags_type; /* Opaque. */
227typedef const struct namei_simple_flags_type *namei_simple_flags_t; /* Gross. */
228extern const namei_simple_flags_t
229	NSM_NOFOLLOW_NOEMULROOT,
230	NSM_NOFOLLOW_TRYEMULROOT,
231	NSM_FOLLOW_NOEMULROOT,
232	NSM_FOLLOW_TRYEMULROOT;
233
234/*
235 * namei_simple_* - the simple cases of namei, with no struct
236 *                  nameidata involved.
237 *
238 * namei_simple_kernel takes a kernel-space path as the first argument.
239 * namei_simple_user takes a user-space path as the first argument.
240 *
241 * A namei call can be converted to namei_simple_* if:
242 *    - the second arg to NDINIT is LOOKUP;
243 *    - it does not need the parent vnode, nd.ni_dvp;
244 *    - the only flags it uses are (NO)FOLLOW and TRYEMULROOT;
245 *    - it does not do anything else gross with the contents of nd.
246 */
247int namei_simple_kernel(const char *, namei_simple_flags_t, struct vnode **);
248int namei_simple_user(const char *, namei_simple_flags_t, struct vnode **);
249
250int	namei(struct nameidata *);
251uint32_t namei_hash(const char *, const char **);
252int	lookup_for_nfsd(struct nameidata *, struct vnode *, int neverfollow);
253int	lookup_for_nfsd_index(struct nameidata *, struct vnode *);
254int	relookup(struct vnode *, struct vnode **, struct componentname *, int);
255void	cache_purge1(struct vnode *, const struct componentname *, int);
256#define	PURGE_PARENTS	1
257#define	PURGE_CHILDREN	2
258#define	cache_purge(vp)	cache_purge1((vp), NULL, PURGE_PARENTS|PURGE_CHILDREN)
259int	cache_lookup(struct vnode *, struct vnode **, struct componentname *);
260int	cache_lookup_raw(struct vnode *, struct vnode **,
261			 struct componentname *);
262int	cache_revlookup(struct vnode *, struct vnode **, char **, char *);
263void	cache_enter(struct vnode *, struct vnode *, struct componentname *);
264void	nchinit(void);
265void	nchreinit(void);
266void	cache_cpu_init(struct cpu_info *);
267void	cache_purgevfs(struct mount *);
268void	namecache_print(struct vnode *, void (*)(const char *, ...));
269
270#endif
271
272/*
273 * Stats on usefulness of namei caches.
274 * XXX: should be 64-bit counters.
275 */
276struct	nchstats {
277	long	ncs_goodhits;		/* hits that we can really use */
278	long	ncs_neghits;		/* negative hits that we can use */
279	long	ncs_badhits;		/* hits we must drop */
280	long	ncs_falsehits;		/* hits with id mismatch */
281	long	ncs_miss;		/* misses */
282	long	ncs_long;		/* long names that ignore cache */
283	long	ncs_pass2;		/* names found with passes == 2 */
284	long	ncs_2passes;		/* number of times we attempt it */
285	long	ncs_revhits;		/* reverse-cache hits */
286	long	ncs_revmiss;		/* reverse-cache misses */
287};
288
289#ifdef _KERNEL
290extern struct nchstats nchstats;
291#endif
292/* #endif !_SYS_NAMEI_H_ (generated by gennameih.awk) */
293