aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index fe00b3b983a8..87bb0258fd27 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -571,9 +571,8 @@ static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
571 571
572 if (inode) { 572 if (inode) {
573 inode->i_mode = mode; 573 inode->i_mode = mode;
574 inode->i_uid = current->fsuid; 574 inode->i_uid = current_fsuid();
575 inode->i_gid = current->fsgid; 575 inode->i_gid = current_fsgid();
576 inode->i_blocks = 0;
577 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 576 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
578 inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info; 577 inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
579 } 578 }
@@ -702,7 +701,7 @@ static int rebind_subsystems(struct cgroupfs_root *root,
702 * any child cgroups exist. This is theoretically supportable 701 * any child cgroups exist. This is theoretically supportable
703 * but involves complex error handling, so it's being left until 702 * but involves complex error handling, so it's being left until
704 * later */ 703 * later */
705 if (!list_empty(&cgrp->children)) 704 if (root->number_of_cgroups > 1)
706 return -EBUSY; 705 return -EBUSY;
707 706
708 /* Process each subsystem */ 707 /* Process each subsystem */
@@ -1024,7 +1023,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
1024 if (ret == -EBUSY) { 1023 if (ret == -EBUSY) {
1025 mutex_unlock(&cgroup_mutex); 1024 mutex_unlock(&cgroup_mutex);
1026 mutex_unlock(&inode->i_mutex); 1025 mutex_unlock(&inode->i_mutex);
1027 goto drop_new_super; 1026 goto free_cg_links;
1028 } 1027 }
1029 1028
1030 /* EBUSY should be the only error here */ 1029 /* EBUSY should be the only error here */
@@ -1073,10 +1072,11 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
1073 1072
1074 return simple_set_mnt(mnt, sb); 1073 return simple_set_mnt(mnt, sb);
1075 1074
1075 free_cg_links:
1076 free_cg_links(&tmp_cg_links);
1076 drop_new_super: 1077 drop_new_super:
1077 up_write(&sb->s_umount); 1078 up_write(&sb->s_umount);
1078 deactivate_super(sb); 1079 deactivate_super(sb);
1079 free_cg_links(&tmp_cg_links);
1080 return ret; 1080 return ret;
1081} 1081}
1082 1082
@@ -1279,6 +1279,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid) 1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1280{ 1280{
1281 struct task_struct *tsk; 1281 struct task_struct *tsk;
1282 const struct cred *cred = current_cred(), *tcred;
1282 int ret; 1283 int ret;
1283 1284
1284 if (pid) { 1285 if (pid) {
@@ -1288,14 +1289,16 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1288 rcu_read_unlock(); 1289 rcu_read_unlock();
1289 return -ESRCH; 1290 return -ESRCH;
1290 } 1291 }
1291 get_task_struct(tsk);
1292 rcu_read_unlock();
1293 1292
1294 if ((current->euid) && (current->euid != tsk->uid) 1293 tcred = __task_cred(tsk);
1295 && (current->euid != tsk->suid)) { 1294 if (cred->euid &&
1296 put_task_struct(tsk); 1295 cred->euid != tcred->uid &&
1296 cred->euid != tcred->suid) {
1297 rcu_read_unlock();
1297 return -EACCES; 1298 return -EACCES;
1298 } 1299 }
1300 get_task_struct(tsk);
1301 rcu_read_unlock();
1299 } else { 1302 } else {
1300 tsk = current; 1303 tsk = current;
1301 get_task_struct(tsk); 1304 get_task_struct(tsk);
@@ -2934,9 +2937,6 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys,
2934 again: 2937 again:
2935 root = subsys->root; 2938 root = subsys->root;
2936 if (root == &rootnode) { 2939 if (root == &rootnode) {
2937 printk(KERN_INFO
2938 "Not cloning cgroup for unused subsystem %s\n",
2939 subsys->name);
2940 mutex_unlock(&cgroup_mutex); 2940 mutex_unlock(&cgroup_mutex);
2941 return 0; 2941 return 0;
2942 } 2942 }
@@ -2944,7 +2944,11 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys,
2944 parent = task_cgroup(tsk, subsys->subsys_id); 2944 parent = task_cgroup(tsk, subsys->subsys_id);
2945 2945
2946 /* Pin the hierarchy */ 2946 /* Pin the hierarchy */
2947 atomic_inc(&parent->root->sb->s_active); 2947 if (!atomic_inc_not_zero(&parent->root->sb->s_active)) {
2948 /* We race with the final deactivate_super() */
2949 mutex_unlock(&cgroup_mutex);
2950 return 0;
2951 }
2948 2952
2949 /* Keep the cgroup alive */ 2953 /* Keep the cgroup alive */
2950 get_css_set(cg); 2954 get_css_set(cg);