mutex_lock(&cgroup_mutex);
 }
 
-static void cgroup_cfts_commit(struct cgroup_subsys *ss,
-                              struct cftype *cfts, bool is_add)
+static int cgroup_cfts_commit(struct cgroup_subsys *ss,
+                             struct cftype *cfts, bool is_add)
        __releases(&cgroup_mutex)
 {
        LIST_HEAD(pending);
        struct dentry *prev = NULL;
        struct inode *inode;
        u64 update_before;
+       int ret = 0;
 
        /* %NULL @cfts indicates abort and don't bother if @ss isn't attached */
        if (!cfts || ss->root == &cgroup_dummy_root ||
            !atomic_inc_not_zero(&sb->s_active)) {
                mutex_unlock(&cgroup_mutex);
-               return;
+               return 0;
        }
 
        /*
        inode = root->dentry->d_inode;
        mutex_lock(&inode->i_mutex);
        mutex_lock(&cgroup_mutex);
-       cgroup_addrm_files(root, ss, cfts, is_add);
+       ret = cgroup_addrm_files(root, ss, cfts, is_add);
        mutex_unlock(&cgroup_mutex);
        mutex_unlock(&inode->i_mutex);
 
+       if (ret)
+               goto out_deact;
+
        /* add/rm files for all cgroups created before */
        rcu_read_lock();
        cgroup_for_each_descendant_pre(cgrp, root) {
                mutex_lock(&inode->i_mutex);
                mutex_lock(&cgroup_mutex);
                if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
-                       cgroup_addrm_files(cgrp, ss, cfts, is_add);
+                       ret = cgroup_addrm_files(cgrp, ss, cfts, is_add);
                mutex_unlock(&cgroup_mutex);
                mutex_unlock(&inode->i_mutex);
 
                rcu_read_lock();
+               if (ret)
+                       break;
        }
        rcu_read_unlock();
        dput(prev);
+out_deact:
        deactivate_super(sb);
+       return ret;
 }
 
 /**
 int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
 {
        struct cftype_set *set;
+       int ret;
 
        set = kzalloc(sizeof(*set), GFP_KERNEL);
        if (!set)
        cgroup_cfts_prepare();
        set->cfts = cfts;
        list_add_tail(&set->node, &ss->cftsets);
-       cgroup_cfts_commit(ss, cfts, true);
-
-       return 0;
+       ret = cgroup_cfts_commit(ss, cfts, true);
+       if (ret)
+               cgroup_rm_cftypes(ss, cfts);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(cgroup_add_cftypes);