Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / dcache.c
index e8bc3420d63edcc28f0992217c860082fe424261..25c0a1b5f6c0ecab691c8081f1f282dacb44175a 100644 (file)
@@ -96,8 +96,6 @@ static struct kmem_cache *dentry_cache __read_mostly;
  * This hash-function tries to avoid losing too many bits of hash
  * information, yet avoid using a prime hash-size or similar.
  */
-#define D_HASHBITS     d_hash_shift
-#define D_HASHMASK     d_hash_mask
 
 static unsigned int d_hash_mask __read_mostly;
 static unsigned int d_hash_shift __read_mostly;
@@ -108,8 +106,7 @@ static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
                                        unsigned int hash)
 {
        hash += (unsigned long) parent / L1_CACHE_BYTES;
-       hash = hash + (hash >> D_HASHBITS);
-       return dentry_hashtable + (hash & D_HASHMASK);
+       return dentry_hashtable + hash_32(hash, d_hash_shift);
 }
 
 /* Statistics gathering. */
@@ -337,23 +334,6 @@ static void dentry_lru_del(struct dentry *dentry)
        }
 }
 
-/*
- * Remove a dentry that is unreferenced and about to be pruned
- * (unhashed and destroyed) from the LRU, and inform the file system.
- * This wrapper should be called _prior_ to unhashing a victim dentry.
- */
-static void dentry_lru_prune(struct dentry *dentry)
-{
-       if (!list_empty(&dentry->d_lru)) {
-               if (dentry->d_flags & DCACHE_OP_PRUNE)
-                       dentry->d_op->d_prune(dentry);
-
-               spin_lock(&dcache_lru_lock);
-               __dentry_lru_del(dentry);
-               spin_unlock(&dcache_lru_lock);
-       }
-}
-
 static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list)
 {
        spin_lock(&dcache_lru_lock);
@@ -486,11 +466,13 @@ relock:
        if (ref)
                dentry->d_count--;
        /*
-        * if dentry was on the d_lru list delete it from there.
         * inform the fs via d_prune that this dentry is about to be
         * unhashed and destroyed.
         */
-       dentry_lru_prune(dentry);
+       if (dentry->d_flags & DCACHE_OP_PRUNE)
+               dentry->d_op->d_prune(dentry);
+
+       dentry_lru_del(dentry);
        /* if it was on the hash then remove it */
        __d_drop(dentry);
        return d_kill(dentry, parent);
@@ -919,11 +901,13 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
                        struct inode *inode;
 
                        /*
-                        * remove the dentry from the lru, and inform
-                        * the fs that this dentry is about to be
+                        * inform the fs that this dentry is about to be
                         * unhashed and destroyed.
                         */
-                       dentry_lru_prune(dentry);
+                       if (dentry->d_flags & DCACHE_OP_PRUNE)
+                               dentry->d_op->d_prune(dentry);
+
+                       dentry_lru_del(dentry);
                        __d_shrink(dentry);
 
                        if (dentry->d_count != 0) {
@@ -1230,8 +1214,10 @@ void shrink_dcache_parent(struct dentry * parent)
        LIST_HEAD(dispose);
        int found;
 
-       while ((found = select_parent(parent, &dispose)) != 0)
+       while ((found = select_parent(parent, &dispose)) != 0) {
                shrink_dentry_list(&dispose);
+               cond_resched();
+       }
 }
 EXPORT_SYMBOL(shrink_dcache_parent);
 
@@ -2408,8 +2394,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
        dentry->d_parent = dentry;
        list_del_init(&dentry->d_u.d_child);
        anon->d_parent = dparent;
-       list_del(&anon->d_u.d_child);
-       list_add(&anon->d_u.d_child, &dparent->d_subdirs);
+       list_move(&anon->d_u.d_child, &dparent->d_subdirs);
 
        write_seqcount_end(&dentry->d_seq);
        write_seqcount_end(&anon->d_seq);
@@ -2698,8 +2683,13 @@ char *d_path(const struct path *path, char *buf, int buflen)
         * thus don't need to be hashed.  They also don't need a name until a
         * user wants to identify the object in /proc/pid/fd/.  The little hack
         * below allows us to generate a name for these objects on demand:
+        *
+        * Some pseudo inodes are mountable.  When they are mounted
+        * path->dentry == path->mnt->mnt_root.  In that case don't call d_dname
+        * and instead have d_path return the mounted path.
         */
-       if (path->dentry->d_op && path->dentry->d_op->d_dname)
+       if (path->dentry->d_op && path->dentry->d_op->d_dname &&
+           (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
                return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        get_fs_root(current->fs, &root);
@@ -2736,6 +2726,17 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
        return memcpy(buffer, temp, sz);
 }
 
+char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+       char *end = buffer + buflen;
+       /* these dentries are never renamed, so d_lock is not needed */
+       if (prepend(&end, &buflen, " (deleted)", 11) ||
+           prepend_name(&end, &buflen, &dentry->d_name) ||
+           prepend(&end, &buflen, "/", 1))
+               end = ERR_PTR(-ENAMETOOLONG);
+       return end;
+}
+
 /*
  * Write full pathname from the root of the filesystem into the buffer.
  */