diff options
| -rw-r--r-- | kernel/cgroup.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ce6db713bbd6..17272893d3b8 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -3369,10 +3369,9 @@ struct cgroup_pidlist { | |||
| 3369 | }; | 3369 | }; |
| 3370 | 3370 | ||
| 3371 | /* seq_file->private points to the following */ | 3371 | /* seq_file->private points to the following */ |
| 3372 | struct cgroup_pidlist_open_file { | 3372 | struct cgroup_open_file { |
| 3373 | enum cgroup_filetype type; | 3373 | struct cfent *cfe; |
| 3374 | struct cgroup *cgrp; | 3374 | void *priv; |
| 3375 | struct cgroup_pidlist *pidlist; | ||
| 3376 | }; | 3375 | }; |
| 3377 | 3376 | ||
| 3378 | /* | 3377 | /* |
| @@ -3689,33 +3688,35 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) | |||
| 3689 | * after a seek to the start). Use a binary-search to find the | 3688 | * after a seek to the start). Use a binary-search to find the |
| 3690 | * next pid to display, if any | 3689 | * next pid to display, if any |
| 3691 | */ | 3690 | */ |
| 3692 | struct cgroup_pidlist_open_file *of = s->private; | 3691 | struct cgroup_open_file *of = s->private; |
| 3693 | struct cgroup *cgrp = of->cgrp; | 3692 | struct cgroup *cgrp = of->cfe->css->cgroup; |
| 3694 | struct cgroup_pidlist *l; | 3693 | struct cgroup_pidlist *l; |
| 3694 | enum cgroup_filetype type = of->cfe->type->private; | ||
| 3695 | int index = 0, pid = *pos; | 3695 | int index = 0, pid = *pos; |
| 3696 | int *iter, ret; | 3696 | int *iter, ret; |
| 3697 | 3697 | ||
| 3698 | mutex_lock(&cgrp->pidlist_mutex); | 3698 | mutex_lock(&cgrp->pidlist_mutex); |
| 3699 | 3699 | ||
| 3700 | /* | 3700 | /* |
| 3701 | * !NULL @of->pidlist indicates that this isn't the first start() | 3701 | * !NULL @of->priv indicates that this isn't the first start() |
| 3702 | * after open. If the matching pidlist is around, we can use that. | 3702 | * after open. If the matching pidlist is around, we can use that. |
| 3703 | * Look for it. Note that @of->pidlist can't be used directly. It | 3703 | * Look for it. Note that @of->priv can't be used directly. It |
| 3704 | * could already have been destroyed. | 3704 | * could already have been destroyed. |
| 3705 | */ | 3705 | */ |
| 3706 | if (of->pidlist) | 3706 | if (of->priv) |
| 3707 | of->pidlist = cgroup_pidlist_find(cgrp, of->type); | 3707 | of->priv = cgroup_pidlist_find(cgrp, type); |
| 3708 | 3708 | ||
| 3709 | /* | 3709 | /* |
| 3710 | * Either this is the first start() after open or the matching | 3710 | * Either this is the first start() after open or the matching |
| 3711 | * pidlist has been destroyed inbetween. Create a new one. | 3711 | * pidlist has been destroyed inbetween. Create a new one. |
| 3712 | */ | 3712 | */ |
| 3713 | if (!of->pidlist) { | 3713 | if (!of->priv) { |
| 3714 | ret = pidlist_array_load(of->cgrp, of->type, &of->pidlist); | 3714 | ret = pidlist_array_load(cgrp, type, |
| 3715 | (struct cgroup_pidlist **)&of->priv); | ||
| 3715 | if (ret) | 3716 | if (ret) |
| 3716 | return ERR_PTR(ret); | 3717 | return ERR_PTR(ret); |
| 3717 | } | 3718 | } |
| 3718 | l = of->pidlist; | 3719 | l = of->priv; |
| 3719 | 3720 | ||
| 3720 | if (pid) { | 3721 | if (pid) { |
| 3721 | int end = l->length; | 3722 | int end = l->length; |
| @@ -3742,19 +3743,19 @@ static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) | |||
| 3742 | 3743 | ||
| 3743 | static void cgroup_pidlist_stop(struct seq_file *s, void *v) | 3744 | static void cgroup_pidlist_stop(struct seq_file *s, void *v) |
| 3744 | { | 3745 | { |
| 3745 | struct cgroup_pidlist_open_file *of = s->private; | 3746 | struct cgroup_open_file *of = s->private; |
| 3747 | struct cgroup_pidlist *l = of->priv; | ||
| 3746 | 3748 | ||
| 3747 | if (of->pidlist) | 3749 | if (l) |
| 3748 | mod_delayed_work(cgroup_pidlist_destroy_wq, | 3750 | mod_delayed_work(cgroup_pidlist_destroy_wq, &l->destroy_dwork, |
| 3749 | &of->pidlist->destroy_dwork, | ||
| 3750 | CGROUP_PIDLIST_DESTROY_DELAY); | 3751 | CGROUP_PIDLIST_DESTROY_DELAY); |
| 3751 | mutex_unlock(&of->cgrp->pidlist_mutex); | 3752 | mutex_unlock(&of->cfe->css->cgroup->pidlist_mutex); |
| 3752 | } | 3753 | } |
| 3753 | 3754 | ||
| 3754 | static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) | 3755 | static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) |
| 3755 | { | 3756 | { |
| 3756 | struct cgroup_pidlist_open_file *of = s->private; | 3757 | struct cgroup_open_file *of = s->private; |
| 3757 | struct cgroup_pidlist *l = of->pidlist; | 3758 | struct cgroup_pidlist *l = of->priv; |
| 3758 | pid_t *p = v; | 3759 | pid_t *p = v; |
| 3759 | pid_t *end = l->list + l->length; | 3760 | pid_t *end = l->list + l->length; |
| 3760 | /* | 3761 | /* |
| @@ -3765,7 +3766,7 @@ static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) | |||
| 3765 | if (p >= end) { | 3766 | if (p >= end) { |
| 3766 | return NULL; | 3767 | return NULL; |
| 3767 | } else { | 3768 | } else { |
| 3768 | *pos = cgroup_pid_fry(of->cgrp, *p); | 3769 | *pos = cgroup_pid_fry(of->cfe->css->cgroup, *p); |
| 3769 | return p; | 3770 | return p; |
| 3770 | } | 3771 | } |
| 3771 | } | 3772 | } |
| @@ -3799,10 +3800,10 @@ static const struct file_operations cgroup_pidlist_operations = { | |||
| 3799 | * in the cgroup. | 3800 | * in the cgroup. |
| 3800 | */ | 3801 | */ |
| 3801 | /* helper function for the two below it */ | 3802 | /* helper function for the two below it */ |
| 3802 | static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) | 3803 | static int cgroup_pidlist_open(struct inode *unused, struct file *file) |
| 3803 | { | 3804 | { |
| 3804 | struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); | 3805 | struct cfent *cfe = __d_cfe(file->f_dentry); |
| 3805 | struct cgroup_pidlist_open_file *of; | 3806 | struct cgroup_open_file *of; |
| 3806 | 3807 | ||
| 3807 | /* configure file information */ | 3808 | /* configure file information */ |
| 3808 | file->f_op = &cgroup_pidlist_operations; | 3809 | file->f_op = &cgroup_pidlist_operations; |
| @@ -3812,18 +3813,9 @@ static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) | |||
| 3812 | if (!of) | 3813 | if (!of) |
| 3813 | return -ENOMEM; | 3814 | return -ENOMEM; |
| 3814 | 3815 | ||
| 3815 | of->type = type; | 3816 | of->cfe = cfe; |
| 3816 | of->cgrp = cgrp; | ||
| 3817 | return 0; | 3817 | return 0; |
| 3818 | } | 3818 | } |
| 3819 | static int cgroup_tasks_open(struct inode *unused, struct file *file) | ||
| 3820 | { | ||
| 3821 | return cgroup_pidlist_open(file, CGROUP_FILE_TASKS); | ||
| 3822 | } | ||
| 3823 | static int cgroup_procs_open(struct inode *unused, struct file *file) | ||
| 3824 | { | ||
| 3825 | return cgroup_pidlist_open(file, CGROUP_FILE_PROCS); | ||
| 3826 | } | ||
| 3827 | 3819 | ||
| 3828 | static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css, | 3820 | static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css, |
| 3829 | struct cftype *cft) | 3821 | struct cftype *cft) |
| @@ -3878,7 +3870,8 @@ static int cgroup_clone_children_write(struct cgroup_subsys_state *css, | |||
| 3878 | static struct cftype cgroup_base_files[] = { | 3870 | static struct cftype cgroup_base_files[] = { |
| 3879 | { | 3871 | { |
| 3880 | .name = "cgroup.procs", | 3872 | .name = "cgroup.procs", |
| 3881 | .open = cgroup_procs_open, | 3873 | .open = cgroup_pidlist_open, |
| 3874 | .private = CGROUP_FILE_PROCS, | ||
| 3882 | .write_u64 = cgroup_procs_write, | 3875 | .write_u64 = cgroup_procs_write, |
| 3883 | .mode = S_IRUGO | S_IWUSR, | 3876 | .mode = S_IRUGO | S_IWUSR, |
| 3884 | }, | 3877 | }, |
| @@ -3902,7 +3895,8 @@ static struct cftype cgroup_base_files[] = { | |||
| 3902 | { | 3895 | { |
| 3903 | .name = "tasks", | 3896 | .name = "tasks", |
| 3904 | .flags = CFTYPE_INSANE, /* use "procs" instead */ | 3897 | .flags = CFTYPE_INSANE, /* use "procs" instead */ |
| 3905 | .open = cgroup_tasks_open, | 3898 | .open = cgroup_pidlist_open, |
| 3899 | .private = CGROUP_FILE_TASKS, | ||
| 3906 | .write_u64 = cgroup_tasks_write, | 3900 | .write_u64 = cgroup_tasks_write, |
| 3907 | .mode = S_IRUGO | S_IWUSR, | 3901 | .mode = S_IRUGO | S_IWUSR, |
| 3908 | }, | 3902 | }, |
