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