more changes on original files
[linux-2.4.git] / include / linux / dcache.h
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 */
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) */
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. */
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
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
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  
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  
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  
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
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 */