cgroup: separate out cgroup_base_files[] handling out of cgroup_populate/clear_dir()
authorTejun Heo <tj@kernel.org>
Fri, 28 Jun 2013 23:24:11 +0000 (16:24 -0700)
committerTejun Heo <tj@kernel.org>
Fri, 12 Jul 2013 19:34:01 +0000 (12:34 -0700)
cgroup_populate/clear_dir() currently take @base_files and adds and
removes, respectively, cgroup_base_files[] to the directory.  File
additions and removals are being reorganized for proper error handling
and more dynamic handling for the unified hierarchy, and mixing base
and subsys file handling into the same functions gets a bit confusing.

This patch moves base file handling out of cgroup_populate/clear_dir()
into their users - cgroup_mount(), cgroup_create() and
cgroup_destroy_locked().

Note that this changes the behavior of base file removal.  If
@base_files is %true, cgroup_clear_dir() used to delete files
regardless of cftype until there's no files left.  Now, only files
with matching cfts are removed.  As files can only be created by the
base or registered cftypes, this shouldn't result in any behavior
difference.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
kernel/cgroup.c

index 36c0ccc921f4e74207194d773b9d37d769556a6e..9835a097f3c0d3c8c21191e78fdf41611ece9ff4 100644 (file)
@@ -215,6 +215,8 @@ static u64 cgroup_serial_nr_next = 1;
  */
 static int need_forkexit_callback __read_mostly;
 
+static struct cftype cgroup_base_files[];
+
 static void cgroup_offline_fn(struct work_struct *work);
 static int cgroup_destroy_locked(struct cgroup *cgrp);
 static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
@@ -804,8 +806,7 @@ static struct cgroup *task_cgroup_from_root(struct task_struct *task,
 static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
 static struct dentry *cgroup_lookup(struct inode *, struct dentry *, unsigned int);
 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
-static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files,
-                              unsigned long subsys_mask);
+static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask);
 static const struct inode_operations cgroup_dir_inode_operations;
 static const struct file_operations proc_cgroupstats_operations;
 
@@ -957,13 +958,11 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
 }
 
 /**
- * cgroup_clear_dir - selective removal of base and subsystem files
+ * cgroup_clear_dir - remove subsys files in a cgroup directory
  * @cgrp: target cgroup
- * @base_files: true if the base files should be removed
  * @subsys_mask: mask of the subsystem ids whose files should be removed
  */
-static void cgroup_clear_dir(struct cgroup *cgrp, bool base_files,
-                            unsigned long subsys_mask)
+static void cgroup_clear_dir(struct cgroup *cgrp, unsigned long subsys_mask)
 {
        struct cgroup_subsys *ss;
 
@@ -974,10 +973,6 @@ static void cgroup_clear_dir(struct cgroup *cgrp, bool base_files,
                list_for_each_entry(set, &ss->cftsets, node)
                        cgroup_addrm_files(cgrp, NULL, set->cfts, false);
        }
-       if (base_files) {
-               while (!list_empty(&cgrp->files))
-                       cgroup_rm_file(cgrp, NULL);
-       }
 }
 
 /*
@@ -1372,17 +1367,17 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
         * this before rebind_subsystems, since rebind_subsystems may
         * change this hierarchy's subsys_list.
         */
-       cgroup_clear_dir(cgrp, false, removed_mask);
+       cgroup_clear_dir(cgrp, removed_mask);
 
        ret = rebind_subsystems(root, added_mask, removed_mask);
        if (ret) {
                /* rebind_subsystems failed, re-populate the removed files */
-               cgroup_populate_dir(cgrp, false, removed_mask);
+               cgroup_populate_dir(cgrp, removed_mask);
                goto out_unlock;
        }
 
        /* re-populate subsystem files */
-       cgroup_populate_dir(cgrp, false, added_mask);
+       cgroup_populate_dir(cgrp, added_mask);
 
        if (opts.release_agent)
                strcpy(root->release_agent_path, opts.release_agent);
@@ -1687,7 +1682,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                BUG_ON(root->number_of_cgroups != 1);
 
                cred = override_creds(&init_cred);
-               cgroup_populate_dir(root_cgrp, true, root->subsys_mask);
+               cgroup_addrm_files(root_cgrp, NULL, cgroup_base_files, true);
+               cgroup_populate_dir(root_cgrp, root->subsys_mask);
                revert_creds(cred);
                mutex_unlock(&cgroup_root_mutex);
                mutex_unlock(&cgroup_mutex);
@@ -4172,23 +4168,14 @@ static struct cftype cgroup_base_files[] = {
 };
 
 /**
- * cgroup_populate_dir - selectively creation of files in a directory
+ * cgroup_populate_dir - create subsys files in a cgroup directory
  * @cgrp: target cgroup
- * @base_files: true if the base files should be added
  * @subsys_mask: mask of the subsystem ids whose files should be added
  */
-static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files,
-                              unsigned long subsys_mask)
+static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
 {
-       int err;
        struct cgroup_subsys *ss;
 
-       if (base_files) {
-               err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
-               if (err < 0)
-                       return err;
-       }
-
        /* process cftsets of each subsystem */
        for_each_root_subsys(cgrp->root, ss) {
                struct cftype_set *set;
@@ -4410,7 +4397,11 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
                }
        }
 
-       err = cgroup_populate_dir(cgrp, true, root->subsys_mask);
+       err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true);
+       if (err)
+               goto err_destroy;
+
+       err = cgroup_populate_dir(cgrp, root->subsys_mask);
        if (err)
                goto err_destroy;
 
@@ -4566,7 +4557,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
         * Clear and remove @cgrp directory.  The removal puts the base ref
         * but we aren't quite done with @cgrp yet, so hold onto it.
         */
-       cgroup_clear_dir(cgrp, true, cgrp->root->subsys_mask);
+       cgroup_clear_dir(cgrp, cgrp->root->subsys_mask);
+       cgroup_addrm_files(cgrp, NULL, cgroup_base_files, false);
        dget(d);
        cgroup_d_remove_dir(d);