]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/dcache.h
fs: dcache scale subdirs
[karo-tx-linux.git] / include / linux / dcache.h
index 6a4aea30aa09db016c11ceabcdc8c4cafb0a9c19..ddf4f55624f773131fc1cd0f1d13e104a045834c 100644 (file)
@@ -87,7 +87,7 @@ full_name_hash(const unsigned char *name, unsigned int len)
 #endif
 
 struct dentry {
-       atomic_t d_count;
+       unsigned int d_count;           /* protected by d_lock */
        unsigned int d_flags;           /* protected by d_lock */
        spinlock_t d_lock;              /* per dentry lock */
        int d_mounted;
@@ -133,30 +133,23 @@ enum dentry_d_lock_class
 
 struct dentry_operations {
        int (*d_revalidate)(struct dentry *, struct nameidata *);
-       int (*d_hash) (struct dentry *, struct qstr *);
-       int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
-       int (*d_delete)(struct dentry *);
+       int (*d_hash)(const struct dentry *, const struct inode *,
+                       struct qstr *);
+       int (*d_compare)(const struct dentry *, const struct inode *,
+                       const struct dentry *, const struct inode *,
+                       unsigned int, const char *, const struct qstr *);
+       int (*d_delete)(const struct dentry *);
        void (*d_release)(struct dentry *);
        void (*d_iput)(struct dentry *, struct inode *);
        char *(*d_dname)(struct dentry *, char *, int);
 };
 
-/* the dentry parameter passed to d_hash and d_compare is the parent
- * directory of the entries to be compared. It is used in case these
- * functions need any directory specific information for determining
- * equivalency classes.  Using the dentry itself might not work, as it
- * might be a negative dentry which has no information associated with
- * it */
-
 /*
-locking rules:
-               big lock        dcache_lock     d_lock   may block
-d_revalidate:  no              no              no       yes
-d_hash         no              no              no       yes
-d_compare:     no              yes             yes      no
-d_delete:      no              yes             no       no
-d_release:     no              no              no       yes
-d_iput:                no              no              no       yes
+ * Locking rules for dentry_operations callbacks are to be found in
+ * Documentation/filesystems/Locking. Keep it updated!
+ *
+ * FUrther descriptions are found in Documentation/filesystems/vfs.txt.
+ * Keep it updated too!
  */
 
 /* d_flags entries */
@@ -191,39 +184,6 @@ d_iput:            no              no              no       yes
 extern spinlock_t dcache_lock;
 extern seqlock_t rename_lock;
 
-/**
- * d_drop - drop a dentry
- * @dentry: dentry to drop
- *
- * d_drop() unhashes the entry from the parent dentry hashes, so that it won't
- * be found through a VFS lookup any more. Note that this is different from
- * deleting the dentry - d_delete will try to mark the dentry negative if
- * possible, giving a successful _negative_ lookup, while d_drop will
- * just make the cache lookup fail.
- *
- * d_drop() is used mainly for stuff that wants to invalidate a dentry for some
- * reason (NFS timeouts or autofs deletes).
- *
- * __d_drop requires dentry->d_lock.
- */
-
-static inline void __d_drop(struct dentry *dentry)
-{
-       if (!(dentry->d_flags & DCACHE_UNHASHED)) {
-               dentry->d_flags |= DCACHE_UNHASHED;
-               hlist_del_rcu(&dentry->d_hash);
-       }
-}
-
-static inline void d_drop(struct dentry *dentry)
-{
-       spin_lock(&dcache_lock);
-       spin_lock(&dentry->d_lock);
-       __d_drop(dentry);
-       spin_unlock(&dentry->d_lock);
-       spin_unlock(&dcache_lock);
-}
-
 static inline int dname_external(struct dentry *dentry)
 {
        return dentry->d_name.name != dentry->d_iname;
@@ -235,6 +195,8 @@ static inline int dname_external(struct dentry *dentry)
 extern void d_instantiate(struct dentry *, struct inode *);
 extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
 extern struct dentry * d_materialise_unique(struct dentry *, struct inode *);
+extern void __d_drop(struct dentry *dentry);
+extern void d_drop(struct dentry *dentry);
 extern void d_delete(struct dentry *);
 
 /* allocate/de-allocate */
@@ -296,6 +258,8 @@ static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *in
        return res;
 }
 
+extern void dentry_update_name_case(struct dentry *, struct qstr *);
+
 /* used for rename() and baskets */
 extern void d_move(struct dentry *, struct dentry *);
 extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
@@ -316,7 +280,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 extern char *__d_path(const struct path *path, struct path *root, char *, int);
 extern char *d_path(const struct path *, char *, int);
 extern char *d_path_with_unreachable(const struct path *, char *, int);
-extern char *__dentry_path(struct dentry *, char *, int);
+extern char *dentry_path_raw(struct dentry *, char *, int);
 extern char *dentry_path(struct dentry *, char *, int);
 
 /* Allocation counts.. */
@@ -333,17 +297,29 @@ extern char *dentry_path(struct dentry *, char *, int);
  *     needs and they take necessary precautions) you should hold dcache_lock
  *     and call dget_locked() instead of dget().
  */
+static inline struct dentry *dget_dlock(struct dentry *dentry)
+{
+       if (dentry) {
+               BUG_ON(!dentry->d_count);
+               dentry->d_count++;
+       }
+       return dentry;
+}
+
 static inline struct dentry *dget(struct dentry *dentry)
 {
        if (dentry) {
-               BUG_ON(!atomic_read(&dentry->d_count));
-               atomic_inc(&dentry->d_count);
+               spin_lock(&dentry->d_lock);
+               dget_dlock(dentry);
+               spin_unlock(&dentry->d_lock);
        }
        return dentry;
 }
 
 extern struct dentry * dget_locked(struct dentry *);
+extern struct dentry * dget_locked_dlock(struct dentry *);
+
+extern struct dentry *dget_parent(struct dentry *dentry);
 
 /**
  *     d_unhashed -    is dentry hashed
@@ -374,16 +350,6 @@ static inline void dont_mount(struct dentry *dentry)
        spin_unlock(&dentry->d_lock);
 }
 
-static inline struct dentry *dget_parent(struct dentry *dentry)
-{
-       struct dentry *ret;
-
-       spin_lock(&dentry->d_lock);
-       ret = dget(dentry->d_parent);
-       spin_unlock(&dentry->d_lock);
-       return ret;
-}
-
 extern void dput(struct dentry *);
 
 static inline int d_mountpoint(struct dentry *dentry)