diff options
author | Tejun Heo <tj@kernel.org> | 2013-05-23 21:53:09 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-05-23 21:53:09 -0400 |
commit | 3f33e64f4a212771a0b5c63eddaa7f81e65223e3 (patch) | |
tree | a212de935bb984849a5bf3bed3618dc9975203db | |
parent | 23958e729e7029678e746bf8f4094c8863a79c3d (diff) | |
parent | 7805d000db30a3787a4c969bab6ae4d8a5fd8ce6 (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.h | 2 | ||||
-rw-r--r-- | kernel/cgroup.c | 18 |
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 | } |