cgroup: convert cgroupfs_root flag bits to masks and add CGRP_ prefix
[deliverable/linux.git] / kernel / cgroup.c
index 65b72d0367c54f3949ec3181e714ee6d77f87b32..67428d84e38bad75fbfa26b0094672bfb0bb7504 100644 (file)
@@ -276,10 +276,30 @@ inline int cgroup_is_removed(const struct cgroup *cgrp)
        return test_bit(CGRP_REMOVED, &cgrp->flags);
 }
 
-/* bits in struct cgroupfs_root flags field */
+/**
+ * cgroup_is_descendant - test ancestry
+ * @cgrp: the cgroup to be tested
+ * @ancestor: possible ancestor of @cgrp
+ *
+ * Test whether @cgrp is a descendant of @ancestor.  It also returns %true
+ * if @cgrp == @ancestor.  This function is safe to call as long as @cgrp
+ * and @ancestor are accessible.
+ */
+bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor)
+{
+       while (cgrp) {
+               if (cgrp == ancestor)
+                       return true;
+               cgrp = cgrp->parent;
+       }
+       return false;
+}
+EXPORT_SYMBOL_GPL(cgroup_is_descendant);
+
+/* cgroupfs_root->flags */
 enum {
-       ROOT_NOPREFIX,  /* mounted subsystems have no named prefix */
-       ROOT_XATTR,     /* supports extended attributes */
+       CGRP_ROOT_NOPREFIX      = (1 << 1), /* mounted subsystems have no named prefix */
+       CGRP_ROOT_XATTR         = (1 << 2), /* supports extended attributes */
 };
 
 static int cgroup_is_releasable(const struct cgroup *cgrp)
@@ -1071,12 +1091,16 @@ static int rebind_subsystems(struct cgroupfs_root *root,
                        cgrp->subsys[i]->cgroup = cgrp;
                        list_move(&ss->sibling, &root->subsys_list);
                        ss->root = root;
+                       if (ss->bind)
+                               ss->bind(cgrp);
                        /* refcount was already taken, and we're keeping it */
                } else if (bit & removed_mask) {
                        /* We're removing this subsystem */
                        BUG_ON(ss == NULL);
                        BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]);
                        BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
+                       if (ss->bind)
+                               ss->bind(dummytop);
                        dummytop->subsys[i]->cgroup = dummytop;
                        cgrp->subsys[i] = NULL;
                        subsys[i]->root = &rootnode;
@@ -1113,9 +1137,9 @@ static int cgroup_show_options(struct seq_file *seq, struct dentry *dentry)
        mutex_lock(&cgroup_root_mutex);
        for_each_subsys(root, ss)
                seq_printf(seq, ",%s", ss->name);
-       if (test_bit(ROOT_NOPREFIX, &root->flags))
+       if (root->flags & CGRP_ROOT_NOPREFIX)
                seq_puts(seq, ",noprefix");
-       if (test_bit(ROOT_XATTR, &root->flags))
+       if (root->flags & CGRP_ROOT_XATTR)
                seq_puts(seq, ",xattr");
        if (strlen(root->release_agent_path))
                seq_printf(seq, ",release_agent=%s", root->release_agent_path);
@@ -1178,7 +1202,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
                        continue;
                }
                if (!strcmp(token, "noprefix")) {
-                       set_bit(ROOT_NOPREFIX, &opts->flags);
+                       opts->flags |= CGRP_ROOT_NOPREFIX;
                        continue;
                }
                if (!strcmp(token, "clone_children")) {
@@ -1186,7 +1210,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
                        continue;
                }
                if (!strcmp(token, "xattr")) {
-                       set_bit(ROOT_XATTR, &opts->flags);
+                       opts->flags |= CGRP_ROOT_XATTR;
                        continue;
                }
                if (!strncmp(token, "release_agent=", 14)) {
@@ -1269,8 +1293,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
         * with the old cpuset, so we allow noprefix only if mounting just
         * the cpuset subsystem.
         */
-       if (test_bit(ROOT_NOPREFIX, &opts->flags) &&
-           (opts->subsys_mask & mask))
+       if ((opts->flags & CGRP_ROOT_NOPREFIX) && (opts->subsys_mask & mask))
                return -EINVAL;
 
 
@@ -1787,11 +1810,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
        int ret = -ENAMETOOLONG;
        char *start;
 
+       if (!cgrp->parent) {
+               if (strlcpy(buf, "/", buflen) >= buflen)
+                       return -ENAMETOOLONG;
+               return 0;
+       }
+
        start = buf + buflen - 1;
        *start = '\0';
 
        rcu_read_lock();
-       while (cgrp) {
+       do {
                const char *name = cgroup_name(cgrp);
                int len;
 
@@ -1800,15 +1829,12 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
                        goto out;
                memcpy(start, name, len);
 
-               if (!cgrp->parent)
-                       break;
-
                if (--start < buf)
                        goto out;
                *start = '/';
 
                cgrp = cgrp->parent;
-       }
+       } while (cgrp->parent);
        ret = 0;
        memmove(buf, start, buf + buflen - start);
 out:
@@ -2499,7 +2525,7 @@ static struct simple_xattrs *__d_xattrs(struct dentry *dentry)
 static inline int xattr_enabled(struct dentry *dentry)
 {
        struct cgroupfs_root *root = dentry->d_sb->s_fs_info;
-       return test_bit(ROOT_XATTR, &root->flags);
+       return root->flags & CGRP_ROOT_XATTR;
 }
 
 static bool is_valid_xattr(const char *name)
@@ -2671,7 +2697,7 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
 
        simple_xattrs_init(&cft->xattrs);
 
-       if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) {
+       if (subsys && !(cgrp->root->flags & CGRP_ROOT_NOPREFIX)) {
                strcpy(name, subsys->name);
                strcat(name, ".");
        }
This page took 0.03754 seconds and 5 git commands to generate.