]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Apr 2015 10:22:00 +0000 (12:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Apr 2015 10:22:00 +0000 (12:22 +0200)
added patches:
move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch

queue-3.14/move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch b/queue-3.14/move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch
new file mode 100644 (file)
index 0000000..d2fd2e6
--- /dev/null
@@ -0,0 +1,734 @@
+From 946e51f2bf37f1656916eb75bd0742ba33983c28 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Sun, 26 Oct 2014 19:19:16 -0400
+Subject: move d_rcu from overlapping d_child to overlapping d_alias
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 946e51f2bf37f1656916eb75bd0742ba33983c28 upstream.
+
+move d_rcu from overlapping d_child to overlapping d_alias
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+[hujianyang: Backported to 3.14 refer to the work of Ben Hutchings in 3.2:
+ - Apply name changes in all the different places we use d_alias and d_child
+ - Move the WARN_ON() in __d_free() to d_free() as we don't have dentry_free()]
+Signed-off-by: hujianyang <hujianyang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/cell/spufs/inode.c       |    2 
+ drivers/staging/lustre/lustre/llite/dcache.c    |    2 
+ drivers/staging/lustre/lustre/llite/llite_lib.c |    2 
+ drivers/staging/lustre/lustre/llite/namei.c     |    8 +--
+ fs/affs/amigaffs.c                              |    2 
+ fs/autofs4/expire.c                             |   12 ++--
+ fs/autofs4/root.c                               |    2 
+ fs/ceph/dir.c                                   |    8 +--
+ fs/ceph/inode.c                                 |    2 
+ fs/cifs/inode.c                                 |    2 
+ fs/coda/cache.c                                 |    2 
+ fs/dcache.c                                     |   58 ++++++++++++------------
+ fs/debugfs/inode.c                              |    2 
+ fs/exportfs/expfs.c                             |    2 
+ fs/libfs.c                                      |   12 ++--
+ fs/ncpfs/dir.c                                  |    2 
+ fs/ncpfs/ncplib_kernel.h                        |    4 -
+ fs/nfs/getroot.c                                |    2 
+ fs/notify/fsnotify.c                            |    4 -
+ fs/ocfs2/dcache.c                               |    2 
+ include/linux/dcache.h                          |    8 +--
+ kernel/cgroup.c                                 |    2 
+ kernel/trace/trace.c                            |    4 -
+ kernel/trace/trace_events.c                     |    2 
+ security/selinux/selinuxfs.c                    |    6 +-
+ 25 files changed, 77 insertions(+), 77 deletions(-)
+
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentr
+       struct dentry *dentry, *tmp;
+       mutex_lock(&dir->d_inode->i_mutex);
+-      list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
++      list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
+               spin_lock(&dentry->d_lock);
+               if (!(d_unhashed(dentry)) && dentry->d_inode) {
+                       dget_dlock(dentry);
+--- a/drivers/staging/lustre/lustre/llite/dcache.c
++++ b/drivers/staging/lustre/lustre/llite/dcache.c
+@@ -278,7 +278,7 @@ void ll_invalidate_aliases(struct inode
+              inode->i_ino, inode->i_generation, inode);
+       ll_lock_dcache(inode);
+-      ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
++      ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) {
+               CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
+                      "inode %p flags %d\n", dentry->d_name.len,
+                      dentry->d_name.name, dentry, dentry->d_parent,
+--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
++++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
+@@ -678,7 +678,7 @@ void lustre_dump_dentry(struct dentry *d
+               return;
+       list_for_each(tmp, &dentry->d_subdirs) {
+-              struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child);
++              struct dentry *d = list_entry(tmp, struct dentry, d_child);
+               lustre_dump_dentry(d, recur - 1);
+       }
+ }
+--- a/drivers/staging/lustre/lustre/llite/namei.c
++++ b/drivers/staging/lustre/lustre/llite/namei.c
+@@ -175,14 +175,14 @@ static void ll_invalidate_negative_child
+       struct ll_d_hlist_node *p;
+       ll_lock_dcache(dir);
+-      ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) {
++      ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_u.d_alias) {
+               spin_lock(&dentry->d_lock);
+               if (!list_empty(&dentry->d_subdirs)) {
+                       struct dentry *child;
+                       list_for_each_entry_safe(child, tmp_subdir,
+                                                &dentry->d_subdirs,
+-                                               d_u.d_child) {
++                                               d_child) {
+                               if (child->d_inode == NULL)
+                                       d_lustre_invalidate(child, 1);
+                       }
+@@ -364,7 +364,7 @@ static struct dentry *ll_find_alias(stru
+       discon_alias = invalid_alias = NULL;
+       ll_lock_dcache(inode);
+-      ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
++      ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_u.d_alias) {
+               LASSERT(alias != dentry);
+               spin_lock(&alias->d_lock);
+@@ -953,7 +953,7 @@ static void ll_get_child_fid(struct inod
+ {
+       struct dentry *parent, *child;
+-      parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias);
++      parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_u.d_alias);
+       child = d_lookup(parent, name);
+       if (child) {
+               if (child->d_inode)
+--- a/fs/affs/amigaffs.c
++++ b/fs/affs/amigaffs.c
+@@ -126,7 +126,7 @@ affs_fix_dcache(struct inode *inode, u32
+ {
+       struct dentry *dentry;
+       spin_lock(&inode->i_lock);
+-      hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+               if (entry_ino == (u32)(long)dentry->d_fsdata) {
+                       dentry->d_fsdata = (void *)inode->i_ino;
+                       break;
+--- a/fs/autofs4/expire.c
++++ b/fs/autofs4/expire.c
+@@ -91,7 +91,7 @@ static struct dentry *get_next_positive_
+       spin_lock(&root->d_lock);
+       if (prev)
+-              next = prev->d_u.d_child.next;
++              next = prev->d_child.next;
+       else {
+               prev = dget_dlock(root);
+               next = prev->d_subdirs.next;
+@@ -105,13 +105,13 @@ cont:
+               return NULL;
+       }
+-      q = list_entry(next, struct dentry, d_u.d_child);
++      q = list_entry(next, struct dentry, d_child);
+       spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
+       /* Already gone or negative dentry (under construction) - try next */
+       if (!d_count(q) || !simple_positive(q)) {
+               spin_unlock(&q->d_lock);
+-              next = q->d_u.d_child.next;
++              next = q->d_child.next;
+               goto cont;
+       }
+       dget_dlock(q);
+@@ -161,13 +161,13 @@ again:
+                               goto relock;
+                       }
+                       spin_unlock(&p->d_lock);
+-                      next = p->d_u.d_child.next;
++                      next = p->d_child.next;
+                       p = parent;
+                       if (next != &parent->d_subdirs)
+                               break;
+               }
+       }
+-      ret = list_entry(next, struct dentry, d_u.d_child);
++      ret = list_entry(next, struct dentry, d_child);
+       spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
+       /* Negative dentry - try next */
+@@ -461,7 +461,7 @@ found:
+       spin_lock(&sbi->lookup_lock);
+       spin_lock(&expired->d_parent->d_lock);
+       spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
+-      list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
++      list_move(&expired->d_parent->d_subdirs, &expired->d_child);
+       spin_unlock(&expired->d_lock);
+       spin_unlock(&expired->d_parent->d_lock);
+       spin_unlock(&sbi->lookup_lock);
+--- a/fs/autofs4/root.c
++++ b/fs/autofs4/root.c
+@@ -655,7 +655,7 @@ static void autofs_clear_leaf_automount_
+       /* only consider parents below dentrys in the root */
+       if (IS_ROOT(parent->d_parent))
+               return;
+-      d_child = &dentry->d_u.d_child;
++      d_child = &dentry->d_child;
+       /* Set parent managed if it's becoming empty */
+       if (d_child->next == &parent->d_subdirs &&
+           d_child->prev == &parent->d_subdirs)
+--- a/fs/ceph/dir.c
++++ b/fs/ceph/dir.c
+@@ -111,7 +111,7 @@ static int fpos_cmp(loff_t l, loff_t r)
+ /*
+  * When possible, we try to satisfy a readdir by peeking at the
+  * dcache.  We make this work by carefully ordering dentries on
+- * d_u.d_child when we initially get results back from the MDS, and
++ * d_child when we initially get results back from the MDS, and
+  * falling back to a "normal" sync readdir if any dentries in the dir
+  * are dropped.
+  *
+@@ -146,11 +146,11 @@ static int __dcache_readdir(struct file
+               p = parent->d_subdirs.prev;
+               dout(" initial p %p/%p\n", p->prev, p->next);
+       } else {
+-              p = last->d_u.d_child.prev;
++              p = last->d_child.prev;
+       }
+ more:
+-      dentry = list_entry(p, struct dentry, d_u.d_child);
++      dentry = list_entry(p, struct dentry, d_child);
+       di = ceph_dentry(dentry);
+       while (1) {
+               dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next,
+@@ -172,7 +172,7 @@ more:
+                    !dentry->d_inode ? " null" : "");
+               spin_unlock(&dentry->d_lock);
+               p = p->prev;
+-              dentry = list_entry(p, struct dentry, d_u.d_child);
++              dentry = list_entry(p, struct dentry, d_child);
+               di = ceph_dentry(dentry);
+       }
+--- a/fs/ceph/inode.c
++++ b/fs/ceph/inode.c
+@@ -1289,7 +1289,7 @@ retry_lookup:
+                       /* reorder parent's d_subdirs */
+                       spin_lock(&parent->d_lock);
+                       spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
+-                      list_move(&dn->d_u.d_child, &parent->d_subdirs);
++                      list_move(&dn->d_child, &parent->d_subdirs);
+                       spin_unlock(&dn->d_lock);
+                       spin_unlock(&parent->d_lock);
+               }
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -883,7 +883,7 @@ inode_has_hashed_dentries(struct inode *
+       struct dentry *dentry;
+       spin_lock(&inode->i_lock);
+-      hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+               if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
+                       spin_unlock(&inode->i_lock);
+                       return true;
+--- a/fs/coda/cache.c
++++ b/fs/coda/cache.c
+@@ -92,7 +92,7 @@ static void coda_flag_children(struct de
+       struct dentry *de;
+       spin_lock(&parent->d_lock);
+-      list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) {
++      list_for_each_entry(de, &parent->d_subdirs, d_child) {
+               /* don't know what to do with negative dentries */
+               if (de->d_inode ) 
+                       coda_flag_inode(de->d_inode, flag);
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -44,7 +44,7 @@
+ /*
+  * Usage:
+  * dcache->d_inode->i_lock protects:
+- *   - i_dentry, d_alias, d_inode of aliases
++ *   - i_dentry, d_u.d_alias, d_inode of aliases
+  * dcache_hash_bucket lock protects:
+  *   - the dcache hash table
+  * s_anon bl list spinlock protects:
+@@ -59,7 +59,7 @@
+  *   - d_unhashed()
+  *   - d_parent and d_subdirs
+  *   - childrens' d_child and d_parent
+- *   - d_alias, d_inode
++ *   - d_u.d_alias, d_inode
+  *
+  * Ordering:
+  * dentry->d_inode->i_lock
+@@ -239,7 +239,6 @@ static void __d_free(struct rcu_head *he
+ {
+       struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
+-      WARN_ON(!hlist_unhashed(&dentry->d_alias));
+       if (dname_external(dentry))
+               kfree(dentry->d_name.name);
+       kmem_cache_free(dentry_cache, dentry); 
+@@ -250,6 +249,7 @@ static void __d_free(struct rcu_head *he
+  */
+ static void d_free(struct dentry *dentry)
+ {
++      WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias));
+       BUG_ON((int)dentry->d_lockref.count > 0);
+       this_cpu_dec(nr_dentry);
+       if (dentry->d_op && dentry->d_op->d_release)
+@@ -288,7 +288,7 @@ static void dentry_iput(struct dentry *
+       struct inode *inode = dentry->d_inode;
+       if (inode) {
+               dentry->d_inode = NULL;
+-              hlist_del_init(&dentry->d_alias);
++              hlist_del_init(&dentry->d_u.d_alias);
+               spin_unlock(&dentry->d_lock);
+               spin_unlock(&inode->i_lock);
+               if (!inode->i_nlink)
+@@ -313,7 +313,7 @@ static void dentry_unlink_inode(struct d
+       struct inode *inode = dentry->d_inode;
+       __d_clear_type(dentry);
+       dentry->d_inode = NULL;
+-      hlist_del_init(&dentry->d_alias);
++      hlist_del_init(&dentry->d_u.d_alias);
+       dentry_rcuwalk_barrier(dentry);
+       spin_unlock(&dentry->d_lock);
+       spin_unlock(&inode->i_lock);
+@@ -435,7 +435,7 @@ static struct dentry *d_kill(struct dent
+       __releases(parent->d_lock)
+       __releases(dentry->d_inode->i_lock)
+ {
+-      list_del(&dentry->d_u.d_child);
++      list_del(&dentry->d_child);
+       /*
+        * Inform d_walk() that we are no longer attached to the
+        * dentry tree
+@@ -737,7 +737,7 @@ static struct dentry *__d_find_alias(str
+ again:
+       discon_alias = NULL;
+-      hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+               spin_lock(&alias->d_lock);
+               if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
+                       if (IS_ROOT(alias) &&
+@@ -790,7 +790,7 @@ void d_prune_aliases(struct inode *inode
+       struct dentry *dentry;
+ restart:
+       spin_lock(&inode->i_lock);
+-      hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+               spin_lock(&dentry->d_lock);
+               if (!dentry->d_lockref.count) {
+                       /*
+@@ -1091,7 +1091,7 @@ repeat:
+ resume:
+       while (next != &this_parent->d_subdirs) {
+               struct list_head *tmp = next;
+-              struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
++              struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+               next = tmp->next;
+               spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+@@ -1143,7 +1143,7 @@ resume:
+                       goto rename_retry;
+               }
+               rcu_read_unlock();
+-              next = child->d_u.d_child.next;
++              next = child->d_child.next;
+               goto resume;
+       }
+       if (need_seqretry(&rename_lock, seq)) {
+@@ -1524,8 +1524,8 @@ struct dentry *__d_alloc(struct super_bl
+       INIT_HLIST_BL_NODE(&dentry->d_hash);
+       INIT_LIST_HEAD(&dentry->d_lru);
+       INIT_LIST_HEAD(&dentry->d_subdirs);
+-      INIT_HLIST_NODE(&dentry->d_alias);
+-      INIT_LIST_HEAD(&dentry->d_u.d_child);
++      INIT_HLIST_NODE(&dentry->d_u.d_alias);
++      INIT_LIST_HEAD(&dentry->d_child);
+       d_set_d_op(dentry, dentry->d_sb->s_d_op);
+       this_cpu_inc(nr_dentry);
+@@ -1555,7 +1555,7 @@ struct dentry *d_alloc(struct dentry * p
+        */
+       __dget_dlock(parent);
+       dentry->d_parent = parent;
+-      list_add(&dentry->d_u.d_child, &parent->d_subdirs);
++      list_add(&dentry->d_child, &parent->d_subdirs);
+       spin_unlock(&parent->d_lock);
+       return dentry;
+@@ -1648,7 +1648,7 @@ static void __d_instantiate(struct dentr
+       spin_lock(&dentry->d_lock);
+       __d_set_type(dentry, add_flags);
+       if (inode)
+-              hlist_add_head(&dentry->d_alias, &inode->i_dentry);
++              hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
+       dentry->d_inode = inode;
+       dentry_rcuwalk_barrier(dentry);
+       spin_unlock(&dentry->d_lock);
+@@ -1672,7 +1672,7 @@ static void __d_instantiate(struct dentr
+  
+ void d_instantiate(struct dentry *entry, struct inode * inode)
+ {
+-      BUG_ON(!hlist_unhashed(&entry->d_alias));
++      BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
+       if (inode)
+               spin_lock(&inode->i_lock);
+       __d_instantiate(entry, inode);
+@@ -1711,7 +1711,7 @@ static struct dentry *__d_instantiate_un
+               return NULL;
+       }
+-      hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+               /*
+                * Don't need alias->d_lock here, because aliases with
+                * d_parent == entry->d_parent are not subject to name or
+@@ -1737,7 +1737,7 @@ struct dentry *d_instantiate_unique(stru
+ {
+       struct dentry *result;
+-      BUG_ON(!hlist_unhashed(&entry->d_alias));
++      BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
+       if (inode)
+               spin_lock(&inode->i_lock);
+@@ -1768,7 +1768,7 @@ EXPORT_SYMBOL(d_instantiate_unique);
+  */
+ int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
+ {
+-      BUG_ON(!hlist_unhashed(&entry->d_alias));
++      BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
+       spin_lock(&inode->i_lock);
+       if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
+@@ -1807,7 +1807,7 @@ static struct dentry * __d_find_any_alia
+       if (hlist_empty(&inode->i_dentry))
+               return NULL;
+-      alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
++      alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
+       __dget(alias);
+       return alias;
+ }
+@@ -1884,7 +1884,7 @@ struct dentry *d_obtain_alias(struct ino
+       spin_lock(&tmp->d_lock);
+       tmp->d_inode = inode;
+       tmp->d_flags |= add_flags;
+-      hlist_add_head(&tmp->d_alias, &inode->i_dentry);
++      hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry);
+       hlist_bl_lock(&tmp->d_sb->s_anon);
+       hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
+       hlist_bl_unlock(&tmp->d_sb->s_anon);
+@@ -2327,7 +2327,7 @@ int d_validate(struct dentry *dentry, st
+       struct dentry *child;
+       spin_lock(&dparent->d_lock);
+-      list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
++      list_for_each_entry(child, &dparent->d_subdirs, d_child) {
+               if (dentry == child) {
+                       spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+                       __dget_dlock(dentry);
+@@ -2574,8 +2574,8 @@ static void __d_move(struct dentry * den
+       /* Unhash the target: dput() will then get rid of it */
+       __d_drop(target);
+-      list_del(&dentry->d_u.d_child);
+-      list_del(&target->d_u.d_child);
++      list_del(&dentry->d_child);
++      list_del(&target->d_child);
+       /* Switch the names.. */
+       switch_names(dentry, target);
+@@ -2585,15 +2585,15 @@ static void __d_move(struct dentry * den
+       if (IS_ROOT(dentry)) {
+               dentry->d_parent = target->d_parent;
+               target->d_parent = target;
+-              INIT_LIST_HEAD(&target->d_u.d_child);
++              INIT_LIST_HEAD(&target->d_child);
+       } else {
+               swap(dentry->d_parent, target->d_parent);
+               /* And add them back to the (new) parent lists */
+-              list_add(&target->d_u.d_child, &target->d_parent->d_subdirs);
++              list_add(&target->d_child, &target->d_parent->d_subdirs);
+       }
+-      list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
++      list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
+       write_seqcount_end(&target->d_seq);
+       write_seqcount_end(&dentry->d_seq);
+@@ -2700,9 +2700,9 @@ static void __d_materialise_dentry(struc
+       swap(dentry->d_name.hash, anon->d_name.hash);
+       dentry->d_parent = dentry;
+-      list_del_init(&dentry->d_u.d_child);
++      list_del_init(&dentry->d_child);
+       anon->d_parent = dparent;
+-      list_move(&anon->d_u.d_child, &dparent->d_subdirs);
++      list_move(&anon->d_child, &dparent->d_subdirs);
+       write_seqcount_end(&dentry->d_seq);
+       write_seqcount_end(&anon->d_seq);
+@@ -3333,7 +3333,7 @@ void d_tmpfile(struct dentry *dentry, st
+ {
+       inode_dec_link_count(inode);
+       BUG_ON(dentry->d_name.name != dentry->d_iname ||
+-              !hlist_unhashed(&dentry->d_alias) ||
++              !hlist_unhashed(&dentry->d_u.d_alias) ||
+               !d_unlinked(dentry));
+       spin_lock(&dentry->d_parent->d_lock);
+       spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -552,7 +552,7 @@ void debugfs_remove_recursive(struct den
+        * use the d_u.d_child as the rcu head and corrupt this list.
+        */
+       spin_lock(&parent->d_lock);
+-      list_for_each_entry(child, &parent->d_subdirs, d_u.d_child) {
++      list_for_each_entry(child, &parent->d_subdirs, d_child) {
+               if (!debugfs_positive(child))
+                       continue;
+--- a/fs/exportfs/expfs.c
++++ b/fs/exportfs/expfs.c
+@@ -50,7 +50,7 @@ find_acceptable_alias(struct dentry *res
+       inode = result->d_inode;
+       spin_lock(&inode->i_lock);
+-      hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+               dget(dentry);
+               spin_unlock(&inode->i_lock);
+               if (toput)
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -113,18 +113,18 @@ loff_t dcache_dir_lseek(struct file *fil
+                       spin_lock(&dentry->d_lock);
+                       /* d_lock not required for cursor */
+-                      list_del(&cursor->d_u.d_child);
++                      list_del(&cursor->d_child);
+                       p = dentry->d_subdirs.next;
+                       while (n && p != &dentry->d_subdirs) {
+                               struct dentry *next;
+-                              next = list_entry(p, struct dentry, d_u.d_child);
++                              next = list_entry(p, struct dentry, d_child);
+                               spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
+                               if (simple_positive(next))
+                                       n--;
+                               spin_unlock(&next->d_lock);
+                               p = p->next;
+                       }
+-                      list_add_tail(&cursor->d_u.d_child, p);
++                      list_add_tail(&cursor->d_child, p);
+                       spin_unlock(&dentry->d_lock);
+               }
+       }
+@@ -149,7 +149,7 @@ int dcache_readdir(struct file *file, st
+ {
+       struct dentry *dentry = file->f_path.dentry;
+       struct dentry *cursor = file->private_data;
+-      struct list_head *p, *q = &cursor->d_u.d_child;
++      struct list_head *p, *q = &cursor->d_child;
+       if (!dir_emit_dots(file, ctx))
+               return 0;
+@@ -158,7 +158,7 @@ int dcache_readdir(struct file *file, st
+               list_move(q, &dentry->d_subdirs);
+       for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
+-              struct dentry *next = list_entry(p, struct dentry, d_u.d_child);
++              struct dentry *next = list_entry(p, struct dentry, d_child);
+               spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
+               if (!simple_positive(next)) {
+                       spin_unlock(&next->d_lock);
+@@ -286,7 +286,7 @@ int simple_empty(struct dentry *dentry)
+       int ret = 0;
+       spin_lock(&dentry->d_lock);
+-      list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
++      list_for_each_entry(child, &dentry->d_subdirs, d_child) {
+               spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
+               if (simple_positive(child)) {
+                       spin_unlock(&child->d_lock);
+--- a/fs/ncpfs/dir.c
++++ b/fs/ncpfs/dir.c
+@@ -406,7 +406,7 @@ ncp_dget_fpos(struct dentry *dentry, str
+       spin_lock(&parent->d_lock);
+       next = parent->d_subdirs.next;
+       while (next != &parent->d_subdirs) {
+-              dent = list_entry(next, struct dentry, d_u.d_child);
++              dent = list_entry(next, struct dentry, d_child);
+               if ((unsigned long)dent->d_fsdata == fpos) {
+                       if (dent->d_inode)
+                               dget(dent);
+--- a/fs/ncpfs/ncplib_kernel.h
++++ b/fs/ncpfs/ncplib_kernel.h
+@@ -194,7 +194,7 @@ ncp_renew_dentries(struct dentry *parent
+       spin_lock(&parent->d_lock);
+       next = parent->d_subdirs.next;
+       while (next != &parent->d_subdirs) {
+-              dentry = list_entry(next, struct dentry, d_u.d_child);
++              dentry = list_entry(next, struct dentry, d_child);
+               if (dentry->d_fsdata == NULL)
+                       ncp_age_dentry(server, dentry);
+@@ -216,7 +216,7 @@ ncp_invalidate_dircache_entries(struct d
+       spin_lock(&parent->d_lock);
+       next = parent->d_subdirs.next;
+       while (next != &parent->d_subdirs) {
+-              dentry = list_entry(next, struct dentry, d_u.d_child);
++              dentry = list_entry(next, struct dentry, d_child);
+               dentry->d_fsdata = NULL;
+               ncp_age_dentry(server, dentry);
+               next = next->next;
+--- a/fs/nfs/getroot.c
++++ b/fs/nfs/getroot.c
+@@ -58,7 +58,7 @@ static int nfs_superblock_set_dummy_root
+                */
+               spin_lock(&sb->s_root->d_inode->i_lock);
+               spin_lock(&sb->s_root->d_lock);
+-              hlist_del_init(&sb->s_root->d_alias);
++              hlist_del_init(&sb->s_root->d_u.d_alias);
+               spin_unlock(&sb->s_root->d_lock);
+               spin_unlock(&sb->s_root->d_inode->i_lock);
+       }
+--- a/fs/notify/fsnotify.c
++++ b/fs/notify/fsnotify.c
+@@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flag
+       spin_lock(&inode->i_lock);
+       /* run all of the dentries associated with this inode.  Since this is a
+        * directory, there damn well better only be one item on this list */
+-      hlist_for_each_entry(alias, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+               struct dentry *child;
+               /* run all of the children of the original inode and fix their
+                * d_flags to indicate parental interest (their parent is the
+                * original inode) */
+               spin_lock(&alias->d_lock);
+-              list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
++              list_for_each_entry(child, &alias->d_subdirs, d_child) {
+                       if (!child->d_inode)
+                               continue;
+--- a/fs/ocfs2/dcache.c
++++ b/fs/ocfs2/dcache.c
+@@ -173,7 +173,7 @@ struct dentry *ocfs2_find_local_alias(st
+       struct dentry *dentry;
+       spin_lock(&inode->i_lock);
+-      hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
++      hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+               spin_lock(&dentry->d_lock);
+               if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
+                       trace_ocfs2_find_local_alias(dentry->d_name.len,
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -124,15 +124,15 @@ struct dentry {
+       void *d_fsdata;                 /* fs-specific data */
+       struct list_head d_lru;         /* LRU list */
++      struct list_head d_child;       /* child of parent list */
++      struct list_head d_subdirs;     /* our children */
+       /*
+-       * d_child and d_rcu can share memory
++       * d_alias and d_rcu can share memory
+        */
+       union {
+-              struct list_head d_child;       /* child of parent list */
++              struct hlist_node d_alias;      /* inode alias list */
+               struct rcu_head d_rcu;
+       } d_u;
+-      struct list_head d_subdirs;     /* our children */
+-      struct hlist_node d_alias;      /* inode alias list */
+ };
+ /*
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -971,7 +971,7 @@ static void cgroup_d_remove_dir(struct d
+       parent = dentry->d_parent;
+       spin_lock(&parent->d_lock);
+       spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+-      list_del_init(&dentry->d_u.d_child);
++      list_del_init(&dentry->d_child);
+       spin_unlock(&dentry->d_lock);
+       spin_unlock(&parent->d_lock);
+       remove_dir(dentry);
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -6158,7 +6158,7 @@ static int instance_mkdir (struct inode
+       int ret;
+       /* Paranoid: Make sure the parent is the "instances" directory */
+-      parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
++      parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
+       if (WARN_ON_ONCE(parent != trace_instance_dir))
+               return -ENOENT;
+@@ -6185,7 +6185,7 @@ static int instance_rmdir(struct inode *
+       int ret;
+       /* Paranoid: Make sure the parent is the "instances" directory */
+-      parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);
++      parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
+       if (WARN_ON_ONCE(parent != trace_instance_dir))
+               return -ENOENT;
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -428,7 +428,7 @@ static void remove_event_file_dir(struct
+       if (dir) {
+               spin_lock(&dir->d_lock);        /* probably unneeded */
+-              list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) {
++              list_for_each_entry(child, &dir->d_subdirs, d_child) {
+                       if (child->d_inode)     /* probably unneeded */
+                               child->d_inode->i_private = NULL;
+               }
+--- a/security/selinux/selinuxfs.c
++++ b/security/selinux/selinuxfs.c
+@@ -1200,7 +1200,7 @@ static void sel_remove_entries(struct de
+       spin_lock(&de->d_lock);
+       node = de->d_subdirs.next;
+       while (node != &de->d_subdirs) {
+-              struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
++              struct dentry *d = list_entry(node, struct dentry, d_child);
+               spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
+               list_del_init(node);
+@@ -1674,12 +1674,12 @@ static void sel_remove_classes(void)
+       list_for_each(class_node, &class_dir->d_subdirs) {
+               struct dentry *class_subdir = list_entry(class_node,
+-                                      struct dentry, d_u.d_child);
++                                      struct dentry, d_child);
+               struct list_head *class_subdir_node;
+               list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
+                       struct dentry *d = list_entry(class_subdir_node,
+-                                              struct dentry, d_u.d_child);
++                                              struct dentry, d_child);
+                       if (d->d_inode)
+                               if (d->d_inode->i_mode & S_IFDIR)
index 160cfeed0029f84b7f5a5c2b3843efcde18d59e5..3c478ffd02b0412d036cd38bf179e074deaac4a3 100644 (file)
@@ -30,3 +30,4 @@ bluetooth-add-usb-device-04ca-3010-as-atheros-ar3012.patch
 mm-hwpoison-drop-lru_add_drain_all-in-__soft_offline_page.patch
 netfilter-conntrack-disable-generic-tracking-for-known-protocols.patch
 kvm-x86-sysenter-emulation-is-broken.patch
+move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch