Merge branch 'for-3.10-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: - Fix for yet another xattr bug which may lead to NULL deref. - A subtle bug in for_each_descendant_pre(). This bug requires quite specific conditions to trigger and isn't too likely to actually happen in the wild, but maybe that just makes it that much more nastier. - A warning message added for silly cgroup re-mount (not -o remount, but unmount followed by mount) behavior. * 'for-3.10-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: warn about mismatching options of a new mount of an existing hierarchy cgroup: fix a subtle bug in descendant pre-order walk cgroup: initialize xattr before calling d_instantiate()
This commit is contained in:
@@ -707,7 +707,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos);
|
|||||||
*
|
*
|
||||||
* If a subsystem synchronizes against the parent in its ->css_online() and
|
* If a subsystem synchronizes against the parent in its ->css_online() and
|
||||||
* before starting iterating, and synchronizes against @pos on each
|
* before starting iterating, and synchronizes against @pos on each
|
||||||
* iteration, any descendant cgroup which finished ->css_offline() is
|
* iteration, any descendant cgroup which finished ->css_online() is
|
||||||
* guaranteed to be visible in the future iterations.
|
* guaranteed to be visible in the future iterations.
|
||||||
*
|
*
|
||||||
* In other words, the following guarantees that a descendant can't escape
|
* In other words, the following guarantees that a descendant can't escape
|
||||||
|
@@ -1686,11 +1686,14 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
|
|||||||
*/
|
*/
|
||||||
cgroup_drop_root(opts.new_root);
|
cgroup_drop_root(opts.new_root);
|
||||||
|
|
||||||
if (((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) &&
|
if (root->flags != opts.flags) {
|
||||||
root->flags != opts.flags) {
|
if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) {
|
||||||
pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
|
pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto drop_new_super;
|
goto drop_new_super;
|
||||||
|
} else {
|
||||||
|
pr_warning("cgroup: new mount options do not match the existing superblock, will be ignored\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no subsys rebinding, so refcounts don't change */
|
/* no subsys rebinding, so refcounts don't change */
|
||||||
@@ -2699,13 +2702,14 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfe->type = (void *)cft;
|
||||||
|
cfe->dentry = dentry;
|
||||||
|
dentry->d_fsdata = cfe;
|
||||||
|
simple_xattrs_init(&cfe->xattrs);
|
||||||
|
|
||||||
mode = cgroup_file_mode(cft);
|
mode = cgroup_file_mode(cft);
|
||||||
error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb);
|
error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
cfe->type = (void *)cft;
|
|
||||||
cfe->dentry = dentry;
|
|
||||||
dentry->d_fsdata = cfe;
|
|
||||||
simple_xattrs_init(&cfe->xattrs);
|
|
||||||
list_add_tail(&cfe->node, &parent->files);
|
list_add_tail(&cfe->node, &parent->files);
|
||||||
cfe = NULL;
|
cfe = NULL;
|
||||||
}
|
}
|
||||||
@@ -2953,11 +2957,8 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
|
|||||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||||
|
|
||||||
/* if first iteration, pretend we just visited @cgroup */
|
/* if first iteration, pretend we just visited @cgroup */
|
||||||
if (!pos) {
|
if (!pos)
|
||||||
if (list_empty(&cgroup->children))
|
|
||||||
return NULL;
|
|
||||||
pos = cgroup;
|
pos = cgroup;
|
||||||
}
|
|
||||||
|
|
||||||
/* visit the first child if exists */
|
/* visit the first child if exists */
|
||||||
next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling);
|
next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling);
|
||||||
@@ -2965,14 +2966,14 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
|
|||||||
return next;
|
return next;
|
||||||
|
|
||||||
/* no child, visit my or the closest ancestor's next sibling */
|
/* no child, visit my or the closest ancestor's next sibling */
|
||||||
do {
|
while (pos != cgroup) {
|
||||||
next = list_entry_rcu(pos->sibling.next, struct cgroup,
|
next = list_entry_rcu(pos->sibling.next, struct cgroup,
|
||||||
sibling);
|
sibling);
|
||||||
if (&next->sibling != &pos->parent->children)
|
if (&next->sibling != &pos->parent->children)
|
||||||
return next;
|
return next;
|
||||||
|
|
||||||
pos = pos->parent;
|
pos = pos->parent;
|
||||||
} while (pos != cgroup);
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user