1#ifndef __LINUX_DCACHE_H
2#define __LINUX_DCACHE_H
3
4#ifdef __KERNEL__
5
6#include <asm/atomic.h>
7#include <linux/mount.h>
8#include <linux/kernel.h>
9
10/*
11 * linux/include/linux/dcache.h
12 *
13 * Dirent cache data structures
14 *
15 * (C) Copyright 1997 Thomas Schoebel-Theuer,
16 * with heavy changes by Linus Torvalds
17 */
18
19#define IS_ROOT(x) ((x) == (x)->d_parent)
20
21/*
22 * "quick string" -- eases parameter passing, but more importantly
23 * saves "metadata" about the string (ie length and the hash).
24 */
25struct qstr {
26	const unsigned char * name;
27	unsigned int len;
28	unsigned int hash;
29};
30
31struct dentry_stat_t {
32	int nr_dentry;
33	int nr_unused;
34	int age_limit;          /* age in seconds */
35	int want_pages;         /* pages requested by system */
36	int dummy[2];
37};
38extern struct dentry_stat_t dentry_stat;
39
40/* Name hashing routines. Initial hash value */
41/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
42#define init_name_hash()		0
43
44/* partial hash update function. Assume roughly 4 bits per character */
45static __inline__ unsigned long partial_name_hash(unsigned long c, unsigned long prevhash)
46{
47	return (prevhash + (c << 4) + (c >> 4)) * 11;
48}
49
50/* Finally: cut down the number of bits to a int value (and try to avoid losing bits) */
51static __inline__ unsigned long end_name_hash(unsigned long hash)
52{
53	return (unsigned int) hash;
54}
55
56/* Compute the hash for a name string. */
57static __inline__ unsigned int full_name_hash(const unsigned char * name, unsigned int len)
58{
59	unsigned long hash = init_name_hash();
60	while (len--)
61		hash = partial_name_hash(*name++, hash);
62	return end_name_hash(hash);
63}
64
65#define DNAME_INLINE_LEN 16
66
67struct dentry {
68	atomic_t d_count;
69	unsigned int d_flags;
70	struct inode  * d_inode;	/* Where the name belongs to - NULL is negative */
71	struct dentry * d_parent;	/* parent directory */
72	struct list_head d_hash;	/* lookup hash list */
73	struct list_head d_lru;		/* d_count = 0 LRU list */
74	struct list_head d_child;	/* child of parent list */
75	struct list_head d_subdirs;	/* our children */
76	struct list_head d_alias;	/* inode alias list */
77	int d_mounted;
78	struct qstr d_name;
79	unsigned long d_time;		/* used by d_revalidate */
80	struct dentry_operations  *d_op;
81	struct super_block * d_sb;	/* The root of the dentry tree */
82	unsigned long d_vfs_flags;
83	void * d_fsdata;		/* fs-specific data */
84	unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
85};
86
87struct dentry_operations {
88	int (*d_revalidate)(struct dentry *, int);
89	int (*d_hash) (struct dentry *, struct qstr *);
90	int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
91	int (*d_delete)(struct dentry *);
92	void (*d_release)(struct dentry *);
93	void (*d_iput)(struct dentry *, struct inode *);
94};
95
96/* the dentry parameter passed to d_hash and d_compare is the parent
97 * directory of the entries to be compared. It is used in case these
98 * functions need any directory specific information for determining
99 * equivalency classes.  Using the dentry itself might not work, as it
100 * might be a negative dentry which has no information associated with
101 * it */
102
103/*
104locking rules:
105		big lock	dcache_lock	may block
106d_revalidate:	no		no		yes
107d_hash		no		no		yes
108d_compare:	no		yes		no
109d_delete:	no		yes		no
110d_release:	no		no		yes
111d_iput:		no		no		yes
112 */
113
114/* d_flags entries */
115#define DCACHE_AUTOFS_PENDING 0x0001    /* autofs: "under construction" */
116#define DCACHE_NFSFS_RENAMED  0x0002    /* this dentry has been "silly
117					 * renamed" and has to be
118					 * deleted on the last dput()
119					 */
120#define	DCACHE_NFSD_DISCONNECTED 0x0004	/* This dentry is not currently connected to the
121					 * dcache tree. Its parent will either be itself,
122					 * or will have this flag as well.
123					 * If this dentry points to a directory, then
124					 * s_nfsd_free_path semaphore will be down
125					 */
126#define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
127
128extern spinlock_t dcache_lock;
129
130/**
131 * d_drop - drop a dentry
132 * @dentry: dentry to drop
133 *
134 * d_drop() unhashes the entry from the parent
135 * dentry hashes, so that it won't be found through
136 * a VFS lookup any more. Note that this is different
137 * from deleting the dentry - d_delete will try to
138 * mark the dentry negative if possible, giving a
139 * successful _negative_ lookup, while d_drop will
140 * just make the cache lookup fail.
141 *
142 * d_drop() is used mainly for stuff that wants
143 * to invalidate a dentry for some reason (NFS
144 * timeouts or autofs deletes).
145 */
146
147static __inline__ void d_drop(struct dentry * dentry)
148{
149	spin_lock(&dcache_lock);
150	list_del(&dentry->d_hash);
151	INIT_LIST_HEAD(&dentry->d_hash);
152	spin_unlock(&dcache_lock);
153}
154
155static __inline__ int dname_external(struct dentry *d)
156{
157	return d->d_name.name != d->d_iname;
158}
159
160/*
161 * These are the low-level FS interfaces to the dcache..
162 */
163extern void d_instantiate(struct dentry *, struct inode *);
164extern void d_delete(struct dentry *);
165
166/* allocate/de-allocate */
167extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
168extern void shrink_dcache_sb(struct super_block *);
169extern void shrink_dcache_parent(struct dentry *);
170extern int d_invalidate(struct dentry *);
171
172#define shrink_dcache() prune_dcache(0)
173struct zone_struct;
174/* dcache memory management */
175extern int shrink_dcache_memory(int, unsigned int);
176extern void prune_dcache(int);
177
178/* icache memory management (defined in linux/fs/inode.c) */
179extern int shrink_icache_memory(int, int);
180extern void prune_icache(int);
181
182/* quota cache memory management (defined in linux/fs/dquot.c) */
183extern int shrink_dqcache_memory(int, unsigned int);
184
185/* only used at mount-time */
186extern struct dentry * d_alloc_root(struct inode *);
187
188/* <clickety>-<click> the ramfs-type tree */
189extern void d_genocide(struct dentry *);
190
191extern struct dentry *d_find_alias(struct inode *);
192extern void d_prune_aliases(struct inode *);
193
194/* test whether we have any submounts in a subdir tree */
195extern int have_submounts(struct dentry *);
196
197/*
198 * This adds the entry to the hash queues.
199 */
200extern void d_rehash(struct dentry *);
201
202/**
203 * d_add - add dentry to hash queues
204 * @entry: dentry to add
205 * @inode: The inode to attach to this dentry
206 *
207 * This adds the entry to the hash queues and initializes @inode.
208 * The entry was actually filled in earlier during d_alloc().
209 */
210
211static __inline__ void d_add(struct dentry * entry, struct inode * inode)
212{
213	d_instantiate(entry, inode);
214	d_rehash(entry);
215}
216
217/* used for rename() and baskets */
218extern void d_move(struct dentry *, struct dentry *);
219
220/* appendix may either be NULL or be used for transname suffixes */
221extern struct dentry * d_lookup(struct dentry *, struct qstr *);
222
223/* validate "insecure" dentry pointer */
224extern int d_validate(struct dentry *, struct dentry *);
225
226extern char * __d_path(struct dentry *, struct vfsmount *, struct dentry *,
227	struct vfsmount *, char *, int);
228
229/* Allocation counts.. */
230
231/**
232 *	dget, dget_locked	-	get a reference to a dentry
233 *	@dentry: dentry to get a reference to
234 *
235 *	Given a dentry or %NULL pointer increment the reference count
236 *	if appropriate and return the dentry. A dentry will not be
237 *	destroyed when it has references. dget() should never be
238 *	called for dentries with zero reference counter. For these cases
239 *	(preferably none, functions in dcache.c are sufficient for normal
240 *	needs and they take necessary precautions) you should hold dcache_lock
241 *	and call dget_locked() instead of dget().
242 */
243
244static __inline__ struct dentry * dget(struct dentry *dentry)
245{
246	if (dentry) {
247		if (!atomic_read(&dentry->d_count))
248			out_of_line_bug();
249		atomic_inc(&dentry->d_count);
250	}
251	return dentry;
252}
253
254extern struct dentry * dget_locked(struct dentry *);
255
256/**
257 *	d_unhashed -	is dentry hashed
258 *	@dentry: entry to check
259 *
260 *	Returns true if the dentry passed is not currently hashed.
261 */
262
263static __inline__ int d_unhashed(struct dentry *dentry)
264{
265	return list_empty(&dentry->d_hash);
266}
267
268extern void dput(struct dentry *);
269
270static __inline__ int d_mountpoint(struct dentry *dentry)
271{
272	return dentry->d_mounted;
273}
274
275extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
276#endif /* __KERNEL__ */
277
278#endif	/* __LINUX_DCACHE_H */
279