Patch "move d_rcu from overlapping d_child to overlapping d_alias" has been added to the 3.10-stable tree
Subsystems (15)
This is a note to let you know that I've just added the patch titled
move d_rcu from overlapping d_child to overlapping d_alias
to the 3.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch
and it can be found in the queue-3.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
946e51f2bf37f1656916eb75bd0742ba33983c28Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Sun, 26 Oct 2014 19:19:16 -0400
Subject: move d_rcu from overlapping d_child to overlapping d_alias
From: Al Viro <[email protected]>
commit 946e51f2bf37f1656916eb75bd0742ba33983c28 upstream.
[hujianyang: Backported to 3.10 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()]
--- arch/powerpc/platforms/cell/spufs/inode.c | 2 fs/affs/amigaffs.c | 2 fs/autofs4/expire.c | 12 ++--- fs/autofs4/root.c | 2 fs/ceph/dir.c | 8 +-- fs/ceph/inode.c | 6 +- fs/cifs/inode.c | 2 fs/coda/cache.c | 2 fs/dcache.c | 72 +++++++++++++++--------------- fs/debugfs/inode.c | 6 +- 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 +- 22 files changed, 82 insertions(+), 82 deletions(-)
arch/powerpc/platforms/cell/spufs/inode.c +1 -1
@@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentrstruct 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);
fs/affs/amigaffs.c +1 -1
@@ -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 ;
fs/autofs4/expire.c +6 -6
@@ -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 (q->d_count ==0 || !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 */
@@ -447,7 +447,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);
fs/autofs4/root.c +1 -1
@@ -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)
fs/ceph/dir.c +4 -4
@@ -103,7 +103,7 @@ static unsigned fpos_off(loff_t p)/* * 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. *
@@ -139,11 +139,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,
@@ -165,7 +165,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); }
fs/ceph/inode.c +3 -3
@@ -867,9 +867,9 @@ static void ceph_set_dentry_offset(strucspin_lock (&dir->d_lock);spin_lock_nested (&dn->d_lock,DENTRY_D_LOCK_NESTED ); -list_move (&dn->d_u.d_child, &dir->d_subdirs); +list_move (&dn->d_child, &dir->d_subdirs);dout ("set_dentry_offset %p %lld (%p %p)\n" , dn, di->offset, - dn->d_u.d_child.prev, dn->d_u.d_child.next); + dn->d_child.prev, dn->d_child.next);spin_unlock (&dn->d_lock);spin_unlock (&dir->d_lock); }
@@ -1296,7 +1296,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); }
fs/cifs/inode.c +1 -1
@@ -832,7 +832,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;
fs/coda/cache.c +1 -1
@@ -92,7 +92,7 @@ static void coda_flag_children(struct destruct 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);
fs/dcache.c +36 -36
267 lines not on this page · raw message
fs/debugfs/inode.c +3 -3
@@ -545,7 +545,7 @@ void debugfs_remove_recursive(struct den parent = dentry; down:mutex_lock (&parent->d_inode->i_mutex); -list_for_each_entry_safe (child, next, &parent->d_subdirs, d_u.d_child) { +list_for_each_entry_safe (child, next, &parent->d_subdirs, d_child) {if (!debugfs_positive (child))continue ;
@@ -566,8 +566,8 @@ void debugfs_remove_recursive(struct denmutex_lock (&parent->d_inode->i_mutex);if (child != dentry) { - next = list_entry(child->d_u.d_child.next, struct dentry, - d_u.d_child); + next = list_entry(child->d_child.next, struct dentry, + d_child); goto up; }
fs/exportfs/expfs.c +1 -1
@@ -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)
fs/libfs.c +6 -6
@@ -104,18 +104,18 @@ loff_t dcache_dir_lseek(struct file *filspin_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); } }
@@ -139,7 +139,7 @@ int dcache_readdir(struct file * filp, v {struct dentry *dentry = filp->f_path.dentry;struct dentry *cursor = filp->private_data; -struct list_head *p, *q = &cursor->d_u.d_child; +struct list_head *p, *q = &cursor->d_child;ino_t ino;int i = filp->f_pos;
@@ -165,7 +165,7 @@ int dcache_readdir(struct file * filp, vfor (p=q->next; p != &dentry->d_subdirs; p=p->next) {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)) {spin_unlock (&next->d_lock);
@@ -289,7 +289,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);
fs/ncpfs/dir.c +1 -1
@@ -391,7 +391,7 @@ ncp_dget_fpos(struct dentry *dentry, strspin_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);
fs/ncpfs/ncplib_kernel.h +2 -2
@@ -194,7 +194,7 @@ ncp_renew_dentries(struct dentry *parentspin_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 dspin_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;
fs/nfs/getroot.c +1 -1
@@ -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); }
fs/notify/fsnotify.c +2 -2
@@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flagspin_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 ;
fs/ocfs2/dcache.c +1 -1
@@ -172,7 +172,7 @@ struct dentry *ocfs2_find_local_alias(ststruct 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,
include/linux/dcache.h +4 -4
@@ -120,15 +120,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 */ };/*
kernel/cgroup.c +1 -1
@@ -984,7 +984,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);
kernel/trace/trace.c +2 -2
@@ -6063,7 +6063,7 @@ static int instance_mkdir (struct inodeint 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 ;
@@ -6090,7 +6090,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 ;
kernel/trace/trace_events.c +1 -1
@@ -425,7 +425,7 @@ static void remove_event_file_dir(structif (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 ; }
security/selinux/selinuxfs.c +3 -3
@@ -1190,7 +1190,7 @@ static void sel_remove_entries(struct despin_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);
@@ -1664,12 +1664,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 )
Patches currently in stable-queue which might be from [email protected] are
queue-3.10/move-d_rcu-from-overlapping-d_child-to-overlapping-d_alias.patch queue-3.10/deal-with-deadlock-in-d_walk.patch