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 */
25 struct qstr {
26 const unsigned char * name;
27 unsigned int len;
28 unsigned int hash;
29 };
30
31 struct 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 };
38 extern 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 */
partial_name_hash(unsigned long c,unsigned long prevhash)45 static __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) */
end_name_hash(unsigned long hash)51 static __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. */
full_name_hash(const unsigned char * name,unsigned int len)57 static __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
67 struct 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
87 struct 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 /*
104 locking rules:
105 big lock dcache_lock may block
106 d_revalidate: no no yes
107 d_hash no no yes
108 d_compare: no yes no
109 d_delete: no yes no
110 d_release: no no yes
111 d_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
128 extern 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
d_drop(struct dentry * dentry)147 static __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
dname_external(struct dentry * d)155 static __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 */
163 extern void d_instantiate(struct dentry *, struct inode *);
164 extern void d_delete(struct dentry *);
165
166 /* allocate/de-allocate */
167 extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
168 extern void shrink_dcache_sb(struct super_block *);
169 extern void shrink_dcache_parent(struct dentry *);
170 extern int d_invalidate(struct dentry *);
171
172 #define shrink_dcache() prune_dcache(0)
173 struct zone_struct;
174 /* dcache memory management */
175 extern int shrink_dcache_memory(int, unsigned int);
176 extern void prune_dcache(int);
177
178 /* icache memory management (defined in linux/fs/inode.c) */
179 extern int shrink_icache_memory(int, int);
180 extern void prune_icache(int);
181
182 /* quota cache memory management (defined in linux/fs/dquot.c) */
183 extern int shrink_dqcache_memory(int, unsigned int);
184
185 /* only used at mount-time */
186 extern struct dentry * d_alloc_root(struct inode *);
187
188 /* <clickety>-<click> the ramfs-type tree */
189 extern void d_genocide(struct dentry *);
190
191 extern struct dentry *d_find_alias(struct inode *);
192 extern void d_prune_aliases(struct inode *);
193
194 /* test whether we have any submounts in a subdir tree */
195 extern int have_submounts(struct dentry *);
196
197 /*
198 * This adds the entry to the hash queues.
199 */
200 extern 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
d_add(struct dentry * entry,struct inode * inode)211 static __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 */
218 extern void d_move(struct dentry *, struct dentry *);
219
220 /* appendix may either be NULL or be used for transname suffixes */
221 extern struct dentry * d_lookup(struct dentry *, struct qstr *);
222
223 /* validate "insecure" dentry pointer */
224 extern int d_validate(struct dentry *, struct dentry *);
225
226 extern 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
dget(struct dentry * dentry)244 static __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
254 extern 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
d_unhashed(struct dentry * dentry)263 static __inline__ int d_unhashed(struct dentry *dentry)
264 {
265 return list_empty(&dentry->d_hash);
266 }
267
268 extern void dput(struct dentry *);
269
d_mountpoint(struct dentry * dentry)270 static __inline__ int d_mountpoint(struct dentry *dentry)
271 {
272 return dentry->d_mounted;
273 }
274
275 extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
276 #endif /* __KERNEL__ */
277
278 #endif /* __LINUX_DCACHE_H */
279