cgroup: s/CGRP_CLONE_CHILDREN/CGRP_CPUSET_CLONE_CHILDREN/
[pandora-kernel.git] / kernel / cgroup.c
index 78a3d5c..2895880 100644 (file)
@@ -296,11 +296,6 @@ static int notify_on_release(const struct cgroup *cgrp)
        return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
 }
 
-static int clone_children(const struct cgroup *cgrp)
-{
-       return test_bit(CGRP_CLONE_CHILDREN, &cgrp->flags);
-}
-
 /*
  * for_each_subsys() allows you to iterate on each subsystem attached to
  * an active hierarchy
@@ -876,7 +871,7 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)
                 * Release the subsystem state objects.
                 */
                for_each_subsys(cgrp->root, ss)
-                       ss->destroy(cgrp);
+                       ss->css_free(cgrp);
 
                cgrp->root->number_of_cgroups--;
                mutex_unlock(&cgroup_mutex);
@@ -1101,7 +1096,7 @@ static int cgroup_show_options(struct seq_file *seq, struct dentry *dentry)
                seq_puts(seq, ",xattr");
        if (strlen(root->release_agent_path))
                seq_printf(seq, ",release_agent=%s", root->release_agent_path);
-       if (clone_children(&root->top_cgroup))
+       if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->top_cgroup.flags))
                seq_puts(seq, ",clone_children");
        if (strlen(root->name))
                seq_printf(seq, ",name=%s", root->name);
@@ -1113,7 +1108,7 @@ struct cgroup_sb_opts {
        unsigned long subsys_mask;
        unsigned long flags;
        char *release_agent;
-       bool clone_children;
+       bool cpuset_clone_children;
        char *name;
        /* User explicitly requested empty subsystem */
        bool none;
@@ -1164,7 +1159,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
                        continue;
                }
                if (!strcmp(token, "clone_children")) {
-                       opts->clone_children = true;
+                       opts->cpuset_clone_children = true;
                        continue;
                }
                if (!strcmp(token, "xattr")) {
@@ -1474,8 +1469,8 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts)
                strcpy(root->release_agent_path, opts->release_agent);
        if (opts->name)
                strcpy(root->name, opts->name);
-       if (opts->clone_children)
-               set_bit(CGRP_CLONE_CHILDREN, &root->top_cgroup.flags);
+       if (opts->cpuset_clone_children)
+               set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->top_cgroup.flags);
        return root;
 }
 
@@ -2657,9 +2652,15 @@ static int cgroup_create_file(struct dentry *dentry, umode_t mode,
                inc_nlink(inode);
                inc_nlink(dentry->d_parent->d_inode);
 
-               /* start with the directory inode held, so that we can
-                * populate it without racing with another mkdir */
-               mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+               /*
+                * Control reaches here with cgroup_mutex held.
+                * @inode->i_mutex should nest outside cgroup_mutex but we
+                * want to populate it immediately without releasing
+                * cgroup_mutex.  As @inode isn't visible to anyone else
+                * yet, trylock will always succeed without affecting
+                * lockdep checks.
+                */
+               WARN_ON_ONCE(!mutex_trylock(&inode->i_mutex));
        } else if (S_ISREG(mode)) {
                inode->i_size = 0;
                inode->i_fop = &cgroup_file_operations;
@@ -3899,7 +3900,7 @@ fail:
 static u64 cgroup_clone_children_read(struct cgroup *cgrp,
                                    struct cftype *cft)
 {
-       return clone_children(cgrp);
+       return test_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags);
 }
 
 static int cgroup_clone_children_write(struct cgroup *cgrp,
@@ -3907,9 +3908,9 @@ static int cgroup_clone_children_write(struct cgroup *cgrp,
                                     u64 val)
 {
        if (val)
-               set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags);
+               set_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags);
        else
-               clear_bit(CGRP_CLONE_CHILDREN, &cgrp->flags);
+               clear_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags);
        return 0;
 }
 
@@ -4035,14 +4036,18 @@ static void init_cgroup_css(struct cgroup_subsys_state *css,
        INIT_WORK(&css->dput_work, css_dput_fn);
 }
 
-/* invoke ->post_create() on a new CSS and mark it online */
-static void online_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
+/* invoke ->post_create() on a new CSS and mark it online if successful */
+static int online_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
+       int ret = 0;
+
        lockdep_assert_held(&cgroup_mutex);
 
-       if (ss->post_create)
-               ss->post_create(cgrp);
-       cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE;
+       if (ss->css_online)
+               ret = ss->css_online(cgrp);
+       if (!ret)
+               cgrp->subsys[ss->subsys_id]->flags |= CSS_ONLINE;
+       return ret;
 }
 
 /* if the CSS is online, invoke ->pre_destory() on it and mark it offline */
@@ -4057,14 +4062,14 @@ static void offline_css(struct cgroup_subsys *ss, struct cgroup *cgrp)
                return;
 
        /*
-        * pre_destroy() should be called with cgroup_mutex unlocked.  See
+        * css_offline() should be called with cgroup_mutex unlocked.  See
         * 3fa59dfbc3 ("cgroup: fix potential deadlock in pre_destroy") for
         * details.  This temporary unlocking should go away once
         * cgroup_mutex is unexported from controllers.
         */
-       if (ss->pre_destroy) {
+       if (ss->css_offline) {
                mutex_unlock(&cgroup_mutex);
-               ss->pre_destroy(cgrp);
+               ss->css_offline(cgrp);
                mutex_lock(&cgroup_mutex);
        }
 
@@ -4101,7 +4106,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
         */
        if (!cgroup_lock_live_group(parent)) {
                err = -ENODEV;
-               goto err_free;
+               goto err_free_cgrp;
        }
 
        /* Grab a reference on the superblock so the hierarchy doesn't
@@ -4120,25 +4125,26 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
        if (notify_on_release(parent))
                set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
 
-       if (clone_children(parent))
-               set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags);
+       if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &parent->flags))
+               set_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags);
 
        for_each_subsys(root, ss) {
                struct cgroup_subsys_state *css;
 
-               css = ss->create(cgrp);
+               css = ss->css_alloc(cgrp);
                if (IS_ERR(css)) {
                        err = PTR_ERR(css);
-                       goto err_destroy;
+                       goto err_free_all;
                }
                init_cgroup_css(css, ss, cgrp);
                if (ss->use_id) {
                        err = alloc_css_id(ss, parent, cgrp);
                        if (err)
-                               goto err_destroy;
+                               goto err_free_all;
                }
-               /* At error, ->destroy() callback has to free assigned ID. */
-               if (clone_children(parent) && ss->post_clone)
+               /* At error, ->css_free() callback has to free assigned ID. */
+               if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &parent->flags) &&
+                   ss->post_clone)
                        ss->post_clone(cgrp);
 
                if (ss->broken_hierarchy && !ss->warned_broken_hierarchy &&
@@ -4158,7 +4164,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
         */
        err = cgroup_create_file(dentry, S_IFDIR | mode, sb);
        if (err < 0)
-               goto err_destroy;
+               goto err_free_all;
        lockdep_assert_held(&dentry->d_inode->i_mutex);
 
        /* allocation complete, commit to creation */
@@ -4168,33 +4174,43 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
        list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children);
        root->number_of_cgroups++;
 
-       for_each_subsys(root, ss) {
-               /* each css holds a ref to the cgroup's dentry */
+       /* each css holds a ref to the cgroup's dentry */
+       for_each_subsys(root, ss)
                dget(dentry);
 
-               /* creation succeeded, notify subsystems */
-               online_css(ss, cgrp);
+       /* creation succeeded, notify subsystems */
+       for_each_subsys(root, ss) {
+               err = online_css(ss, cgrp);
+               if (err)
+                       goto err_destroy;
        }
 
        err = cgroup_populate_dir(cgrp, true, root->subsys_mask);
-       /* If err < 0, we have a half-filled directory - oh well ;) */
+       if (err)
+               goto err_destroy;
 
        mutex_unlock(&cgroup_mutex);
        mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
 
        return 0;
 
-err_destroy:
+err_free_all:
        for_each_subsys(root, ss) {
                if (cgrp->subsys[ss->subsys_id])
-                       ss->destroy(cgrp);
+                       ss->css_free(cgrp);
        }
        mutex_unlock(&cgroup_mutex);
        /* Release the reference count that we took on the superblock */
        deactivate_super(sb);
-err_free:
+err_free_cgrp:
        kfree(cgrp);
        return err;
+
+err_destroy:
+       cgroup_destroy_locked(cgrp);
+       mutex_unlock(&cgroup_mutex);
+       mutex_unlock(&dentry->d_inode->i_mutex);
+       return err;
 }
 
 static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -4361,7 +4377,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
        /* Create the top cgroup state for this subsystem */
        list_add(&ss->sibling, &rootnode.subsys_list);
        ss->root = &rootnode;
-       css = ss->create(dummytop);
+       css = ss->css_alloc(dummytop);
        /* We don't handle early failures gracefully */
        BUG_ON(IS_ERR(css));
        init_cgroup_css(css, ss, dummytop);
@@ -4380,7 +4396,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
        BUG_ON(!list_empty(&init_task.tasks));
 
        ss->active = 1;
-       online_css(ss, dummytop);
+       BUG_ON(online_css(ss, dummytop));
 
        mutex_unlock(&cgroup_mutex);
 
@@ -4400,12 +4416,12 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
  */
 int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 {
-       int i;
        struct cgroup_subsys_state *css;
+       int i, ret;
 
        /* check name and function validity */
        if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN ||
-           ss->create == NULL || ss->destroy == NULL)
+           ss->css_alloc == NULL || ss->css_free == NULL)
                return -EINVAL;
 
        /*
@@ -4434,10 +4450,11 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
        subsys[ss->subsys_id] = ss;
 
        /*
-        * no ss->create seems to need anything important in the ss struct, so
-        * this can happen first (i.e. before the rootnode attachment).
+        * no ss->css_alloc seems to need anything important in the ss
+        * struct, so this can happen first (i.e. before the rootnode
+        * attachment).
         */
-       css = ss->create(dummytop);
+       css = ss->css_alloc(dummytop);
        if (IS_ERR(css)) {
                /* failure case - need to deassign the subsys[] slot. */
                subsys[ss->subsys_id] = NULL;
@@ -4452,15 +4469,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
        init_cgroup_css(css, ss, dummytop);
        /* init_idr must be after init_cgroup_css because it sets css->id. */
        if (ss->use_id) {
-               int ret = cgroup_init_idr(ss, css);
-               if (ret) {
-                       ss->destroy(dummytop);
-                       dummytop->subsys[ss->subsys_id] = NULL;
-                       subsys[ss->subsys_id] = NULL;
-                       list_del_init(&ss->sibling);
-                       mutex_unlock(&cgroup_mutex);
-                       return ret;
-               }
+               ret = cgroup_init_idr(ss, css);
+               if (ret)
+                       goto err_unload;
        }
 
        /*
@@ -4493,11 +4504,19 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
        write_unlock(&css_set_lock);
 
        ss->active = 1;
-       online_css(ss, dummytop);
+       ret = online_css(ss, dummytop);
+       if (ret)
+               goto err_unload;
 
        /* success! */
        mutex_unlock(&cgroup_mutex);
        return 0;
+
+err_unload:
+       mutex_unlock(&cgroup_mutex);
+       /* @ss can't be mounted here as try_module_get() would fail */
+       cgroup_unload_subsys(ss);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(cgroup_load_subsys);
 
@@ -4548,7 +4567,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
                struct css_set *cg = link->cg;
 
                hlist_del(&cg->hlist);
-               BUG_ON(!cg->subsys[ss->subsys_id]);
                cg->subsys[ss->subsys_id] = NULL;
                hhead = css_set_hash(cg->subsys);
                hlist_add_head(&cg->hlist, hhead);
@@ -4556,12 +4574,12 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
        write_unlock(&css_set_lock);
 
        /*
-        * remove subsystem's css from the dummytop and free it - need to free
-        * before marking as null because ss->destroy needs the cgrp->subsys
-        * pointer to find their state. note that this also takes care of
-        * freeing the css_id.
+        * remove subsystem's css from the dummytop and free it - need to
+        * free before marking as null because ss->css_free needs the
+        * cgrp->subsys pointer to find their state. note that this also
+        * takes care of freeing the css_id.
         */
-       ss->destroy(dummytop);
+       ss->css_free(dummytop);
        dummytop->subsys[ss->subsys_id] = NULL;
 
        mutex_unlock(&cgroup_mutex);
@@ -4605,8 +4623,8 @@ int __init cgroup_init_early(void)
 
                BUG_ON(!ss->name);
                BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
-               BUG_ON(!ss->create);
-               BUG_ON(!ss->destroy);
+               BUG_ON(!ss->css_alloc);
+               BUG_ON(!ss->css_free);
                if (ss->subsys_id != i) {
                        printk(KERN_ERR "cgroup: Subsys %s id == %d\n",
                               ss->name, ss->subsys_id);
@@ -5418,7 +5436,7 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
 }
 
 #ifdef CONFIG_CGROUP_DEBUG
-static struct cgroup_subsys_state *debug_create(struct cgroup *cont)
+static struct cgroup_subsys_state *debug_css_alloc(struct cgroup *cont)
 {
        struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL);
 
@@ -5428,7 +5446,7 @@ static struct cgroup_subsys_state *debug_create(struct cgroup *cont)
        return css;
 }
 
-static void debug_destroy(struct cgroup *cont)
+static void debug_css_free(struct cgroup *cont)
 {
        kfree(cont->subsys[debug_subsys_id]);
 }
@@ -5557,8 +5575,8 @@ static struct cftype debug_files[] =  {
 
 struct cgroup_subsys debug_subsys = {
        .name = "debug",
-       .create = debug_create,
-       .destroy = debug_destroy,
+       .css_alloc = debug_css_alloc,
+       .css_free = debug_css_free,
        .subsys_id = debug_subsys_id,
        .base_cftypes = debug_files,
 };