Subversion Repositories shark

Rev

Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed

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