aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-05-23 21:53:09 -0400
committerTejun Heo <tj@kernel.org>2013-05-23 21:53:09 -0400
commit3f33e64f4a212771a0b5c63eddaa7f81e65223e3 (patch)
treea212de935bb984849a5bf3bed3618dc9975203db
parent23958e729e7029678e746bf8f4094c8863a79c3d (diff)
parent7805d000db30a3787a4c969bab6ae4d8a5fd8ce6 (diff)
Merge branch 'for-3.10-fixes' into for-3.11
Merging to receive 7805d000db ("cgroup: fix a subtle bug in descendant pre-order walk") so that further iterator updates can build upon it. Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--kernel/cgroup.c18
2 files changed, 9 insertions, 11 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 4f6f5138c340..1df5f699be61 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -709,7 +709,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos);
709 * 709 *
710 * If a subsystem synchronizes against the parent in its ->css_online() and 710 * If a subsystem synchronizes against the parent in its ->css_online() and
711 * before starting iterating, and synchronizes against @pos on each 711 * before starting iterating, and synchronizes against @pos on each
712 * iteration, any descendant cgroup which finished ->css_offline() is 712 * iteration, any descendant cgroup which finished ->css_online() is
713 * guaranteed to be visible in the future iterations. 713 * guaranteed to be visible in the future iterations.
714 * 714 *
715 * In other words, the following guarantees that a descendant can't escape 715 * In other words, the following guarantees that a descendant can't escape
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 6b2b1d945df2..a19419f4af1a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2736,13 +2736,14 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
2736 goto out; 2736 goto out;
2737 } 2737 }
2738 2738
2739 cfe->type = (void *)cft;
2740 cfe->dentry = dentry;
2741 dentry->d_fsdata = cfe;
2742 simple_xattrs_init(&cfe->xattrs);
2743
2739 mode = cgroup_file_mode(cft); 2744 mode = cgroup_file_mode(cft);
2740 error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb); 2745 error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb);
2741 if (!error) { 2746 if (!error) {
2742 cfe->type = (void *)cft;
2743 cfe->dentry = dentry;
2744 dentry->d_fsdata = cfe;
2745 simple_xattrs_init(&cfe->xattrs);
2746 list_add_tail(&cfe->node, &parent->files); 2747 list_add_tail(&cfe->node, &parent->files);
2747 cfe = NULL; 2748 cfe = NULL;
2748 } 2749 }
@@ -2990,11 +2991,8 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
2990 WARN_ON_ONCE(!rcu_read_lock_held()); 2991 WARN_ON_ONCE(!rcu_read_lock_held());
2991 2992
2992 /* if first iteration, pretend we just visited @cgroup */ 2993 /* if first iteration, pretend we just visited @cgroup */
2993 if (!pos) { 2994 if (!pos)
2994 if (list_empty(&cgroup->children))
2995 return NULL;
2996 pos = cgroup; 2995 pos = cgroup;
2997 }
2998 2996
2999 /* visit the first child if exists */ 2997 /* visit the first child if exists */
3000 next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling); 2998 next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling);
@@ -3002,14 +3000,14 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
3002 return next; 3000 return next;
3003 3001
3004 /* no child, visit my or the closest ancestor's next sibling */ 3002 /* no child, visit my or the closest ancestor's next sibling */
3005 do { 3003 while (pos != cgroup) {
3006 next = list_entry_rcu(pos->sibling.next, struct cgroup, 3004 next = list_entry_rcu(pos->sibling.next, struct cgroup,
3007 sibling); 3005 sibling);
3008 if (&next->sibling != &pos->parent->children) 3006 if (&next->sibling != &pos->parent->children)
3009 return next; 3007 return next;
3010 3008
3011 pos = pos->parent; 3009 pos = pos->parent;
3012 } while (pos != cgroup); 3010 }
3013 3011
3014 return NULL; 3012 return NULL;
3015} 3013}