cgroup: replace cftype->write_string() with cftype->write()
Convert all cftype->write_string() users to the new cftype->write() which maps directly to kernfs write operation and has full access to kernfs and cgroup contexts. The conversions are mostly mechanical. * @css and @cft are accessed using of_css() and of_cft() accessors respectively instead of being specified as arguments. * Should return @nbytes on success instead of 0. * @buf is not trimmed automatically. Trim if necessary. Note that blkcg and netprio don't need this as the parsers already handle whitespaces. cftype->write_string() has no user left after the conversions and removed. While at it, remove unnecessary local variable @p in cgroup_subtree_control_write() and stale comment about CGROUP_LOCAL_BUFFER_SIZE in cgroup_freezer.c. This patch doesn't introduce any visible behavior changes. v2: netprio was missing from conversion. Converted. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Aristeu Rozanski <arozansk@redhat.com> Acked-by: Vivek Goyal <vgoyal@redhat.com> Acked-by: Li Zefan <lizefan@huawei.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: "David S. Miller" <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								b41686401e
							
						
					
				
			
			
				commit
				
					
						451af504df
					
				
			
		
					 11 changed files with 124 additions and 125 deletions
				
			
		| 
						 | 
					@ -1346,10 +1346,10 @@ static int tg_print_conf_uint(struct seq_file *sf, void *v)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t tg_set_conf(struct kernfs_open_file *of,
 | 
				
			||||||
		       const char *buf, bool is_u64)
 | 
								   char *buf, size_t nbytes, loff_t off, bool is_u64)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct blkcg *blkcg = css_to_blkcg(css);
 | 
						struct blkcg *blkcg = css_to_blkcg(of_css(of));
 | 
				
			||||||
	struct blkg_conf_ctx ctx;
 | 
						struct blkg_conf_ctx ctx;
 | 
				
			||||||
	struct throtl_grp *tg;
 | 
						struct throtl_grp *tg;
 | 
				
			||||||
	struct throtl_service_queue *sq;
 | 
						struct throtl_service_queue *sq;
 | 
				
			||||||
| 
						 | 
					@ -1368,9 +1368,9 @@ static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
		ctx.v = -1;
 | 
							ctx.v = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (is_u64)
 | 
						if (is_u64)
 | 
				
			||||||
		*(u64 *)((void *)tg + cft->private) = ctx.v;
 | 
							*(u64 *)((void *)tg + of_cft(of)->private) = ctx.v;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		*(unsigned int *)((void *)tg + cft->private) = ctx.v;
 | 
							*(unsigned int *)((void *)tg + of_cft(of)->private) = ctx.v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	throtl_log(&tg->service_queue,
 | 
						throtl_log(&tg->service_queue,
 | 
				
			||||||
		   "limit change rbps=%llu wbps=%llu riops=%u wiops=%u",
 | 
							   "limit change rbps=%llu wbps=%llu riops=%u wiops=%u",
 | 
				
			||||||
| 
						 | 
					@ -1404,19 +1404,19 @@ static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	blkg_conf_finish(&ctx);
 | 
						blkg_conf_finish(&ctx);
 | 
				
			||||||
	return 0;
 | 
						return nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tg_set_conf_u64(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t tg_set_conf_u64(struct kernfs_open_file *of,
 | 
				
			||||||
			   char *buf)
 | 
								       char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return tg_set_conf(css, cft, buf, true);
 | 
						return tg_set_conf(of, buf, nbytes, off, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tg_set_conf_uint(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t tg_set_conf_uint(struct kernfs_open_file *of,
 | 
				
			||||||
			    char *buf)
 | 
									char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return tg_set_conf(css, cft, buf, false);
 | 
						return tg_set_conf(of, buf, nbytes, off, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct cftype throtl_files[] = {
 | 
					static struct cftype throtl_files[] = {
 | 
				
			||||||
| 
						 | 
					@ -1424,25 +1424,25 @@ static struct cftype throtl_files[] = {
 | 
				
			||||||
		.name = "throttle.read_bps_device",
 | 
							.name = "throttle.read_bps_device",
 | 
				
			||||||
		.private = offsetof(struct throtl_grp, bps[READ]),
 | 
							.private = offsetof(struct throtl_grp, bps[READ]),
 | 
				
			||||||
		.seq_show = tg_print_conf_u64,
 | 
							.seq_show = tg_print_conf_u64,
 | 
				
			||||||
		.write_string = tg_set_conf_u64,
 | 
							.write = tg_set_conf_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "throttle.write_bps_device",
 | 
							.name = "throttle.write_bps_device",
 | 
				
			||||||
		.private = offsetof(struct throtl_grp, bps[WRITE]),
 | 
							.private = offsetof(struct throtl_grp, bps[WRITE]),
 | 
				
			||||||
		.seq_show = tg_print_conf_u64,
 | 
							.seq_show = tg_print_conf_u64,
 | 
				
			||||||
		.write_string = tg_set_conf_u64,
 | 
							.write = tg_set_conf_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "throttle.read_iops_device",
 | 
							.name = "throttle.read_iops_device",
 | 
				
			||||||
		.private = offsetof(struct throtl_grp, iops[READ]),
 | 
							.private = offsetof(struct throtl_grp, iops[READ]),
 | 
				
			||||||
		.seq_show = tg_print_conf_uint,
 | 
							.seq_show = tg_print_conf_uint,
 | 
				
			||||||
		.write_string = tg_set_conf_uint,
 | 
							.write = tg_set_conf_uint,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "throttle.write_iops_device",
 | 
							.name = "throttle.write_iops_device",
 | 
				
			||||||
		.private = offsetof(struct throtl_grp, iops[WRITE]),
 | 
							.private = offsetof(struct throtl_grp, iops[WRITE]),
 | 
				
			||||||
		.seq_show = tg_print_conf_uint,
 | 
							.seq_show = tg_print_conf_uint,
 | 
				
			||||||
		.write_string = tg_set_conf_uint,
 | 
							.write = tg_set_conf_uint,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "throttle.io_service_bytes",
 | 
							.name = "throttle.io_service_bytes",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1670,11 +1670,11 @@ static int cfq_print_leaf_weight(struct seq_file *sf, void *v)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __cfqg_set_weight_device(struct cgroup_subsys_state *css,
 | 
					static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
 | 
				
			||||||
				    struct cftype *cft, const char *buf,
 | 
										char *buf, size_t nbytes, loff_t off,
 | 
				
			||||||
					bool is_leaf_weight)
 | 
										bool is_leaf_weight)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct blkcg *blkcg = css_to_blkcg(css);
 | 
						struct blkcg *blkcg = css_to_blkcg(of_css(of));
 | 
				
			||||||
	struct blkg_conf_ctx ctx;
 | 
						struct blkg_conf_ctx ctx;
 | 
				
			||||||
	struct cfq_group *cfqg;
 | 
						struct cfq_group *cfqg;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -1697,19 +1697,19 @@ static int __cfqg_set_weight_device(struct cgroup_subsys_state *css,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	blkg_conf_finish(&ctx);
 | 
						blkg_conf_finish(&ctx);
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cfqg_set_weight_device(struct cgroup_subsys_state *css,
 | 
					static ssize_t cfqg_set_weight_device(struct kernfs_open_file *of,
 | 
				
			||||||
				  struct cftype *cft, char *buf)
 | 
									      char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __cfqg_set_weight_device(css, cft, buf, false);
 | 
						return __cfqg_set_weight_device(of, buf, nbytes, off, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cfqg_set_leaf_weight_device(struct cgroup_subsys_state *css,
 | 
					static ssize_t cfqg_set_leaf_weight_device(struct kernfs_open_file *of,
 | 
				
			||||||
				       struct cftype *cft, char *buf)
 | 
										   char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __cfqg_set_weight_device(css, cft, buf, true);
 | 
						return __cfqg_set_weight_device(of, buf, nbytes, off, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static int __cfq_set_weight(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
| 
						 | 
					@ -1837,7 +1837,7 @@ static struct cftype cfq_blkcg_files[] = {
 | 
				
			||||||
		.name = "weight_device",
 | 
							.name = "weight_device",
 | 
				
			||||||
		.flags = CFTYPE_ONLY_ON_ROOT,
 | 
							.flags = CFTYPE_ONLY_ON_ROOT,
 | 
				
			||||||
		.seq_show = cfqg_print_leaf_weight_device,
 | 
							.seq_show = cfqg_print_leaf_weight_device,
 | 
				
			||||||
		.write_string = cfqg_set_leaf_weight_device,
 | 
							.write = cfqg_set_leaf_weight_device,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "weight",
 | 
							.name = "weight",
 | 
				
			||||||
| 
						 | 
					@ -1851,7 +1851,7 @@ static struct cftype cfq_blkcg_files[] = {
 | 
				
			||||||
		.name = "weight_device",
 | 
							.name = "weight_device",
 | 
				
			||||||
		.flags = CFTYPE_NOT_ON_ROOT,
 | 
							.flags = CFTYPE_NOT_ON_ROOT,
 | 
				
			||||||
		.seq_show = cfqg_print_weight_device,
 | 
							.seq_show = cfqg_print_weight_device,
 | 
				
			||||||
		.write_string = cfqg_set_weight_device,
 | 
							.write = cfqg_set_weight_device,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "weight",
 | 
							.name = "weight",
 | 
				
			||||||
| 
						 | 
					@ -1863,7 +1863,7 @@ static struct cftype cfq_blkcg_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "leaf_weight_device",
 | 
							.name = "leaf_weight_device",
 | 
				
			||||||
		.seq_show = cfqg_print_leaf_weight_device,
 | 
							.seq_show = cfqg_print_leaf_weight_device,
 | 
				
			||||||
		.write_string = cfqg_set_leaf_weight_device,
 | 
							.write = cfqg_set_leaf_weight_device,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "leaf_weight",
 | 
							.name = "leaf_weight",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -453,8 +453,7 @@ struct cftype {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The maximum length of string, excluding trailing nul, that can
 | 
						 * The maximum length of string, excluding trailing nul, that can
 | 
				
			||||||
	 * be passed to write_string.  If < PAGE_SIZE-1, PAGE_SIZE-1 is
 | 
						 * be passed to write.  If < PAGE_SIZE-1, PAGE_SIZE-1 is assumed.
 | 
				
			||||||
	 * assumed.
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	size_t max_write_len;
 | 
						size_t max_write_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -500,13 +499,6 @@ struct cftype {
 | 
				
			||||||
	int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
						int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
			 s64 val);
 | 
								 s64 val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * write_string() is passed a nul-terminated kernelspace
 | 
					 | 
				
			||||||
	 * buffer of maximum length determined by max_write_len.
 | 
					 | 
				
			||||||
	 * Returns 0 or -ve error code.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	int (*write_string)(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					 | 
				
			||||||
			    char *buffer);
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * trigger() callback can be used to get some kick from the
 | 
						 * trigger() callback can be used to get some kick from the
 | 
				
			||||||
	 * userspace, when the actual string written is not important
 | 
						 * userspace, when the actual string written is not important
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1035,7 +1035,7 @@ static umode_t cgroup_file_mode(const struct cftype *cft)
 | 
				
			||||||
		mode |= S_IRUGO;
 | 
							mode |= S_IRUGO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cft->write_u64 || cft->write_s64 || cft->write ||
 | 
						if (cft->write_u64 || cft->write_s64 || cft->write ||
 | 
				
			||||||
	    cft->write_string || cft->trigger)
 | 
						    cft->trigger)
 | 
				
			||||||
		mode |= S_IWUSR;
 | 
							mode |= S_IWUSR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mode;
 | 
						return mode;
 | 
				
			||||||
| 
						 | 
					@ -2352,20 +2352,21 @@ static int cgroup_procs_write(struct cgroup_subsys_state *css,
 | 
				
			||||||
	return attach_task_by_pid(css->cgroup, tgid, true);
 | 
						return attach_task_by_pid(css->cgroup, tgid, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cgroup_release_agent_write(struct cgroup_subsys_state *css,
 | 
					static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of,
 | 
				
			||||||
				      struct cftype *cft, char *buffer)
 | 
										  char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cgroup_root *root = css->cgroup->root;
 | 
						struct cgroup *cgrp = of_css(of)->cgroup;
 | 
				
			||||||
 | 
						struct cgroup_root *root = cgrp->root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUILD_BUG_ON(sizeof(root->release_agent_path) < PATH_MAX);
 | 
						BUILD_BUG_ON(sizeof(root->release_agent_path) < PATH_MAX);
 | 
				
			||||||
	if (!cgroup_lock_live_group(css->cgroup))
 | 
						if (!cgroup_lock_live_group(cgrp))
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
	spin_lock(&release_agent_path_lock);
 | 
						spin_lock(&release_agent_path_lock);
 | 
				
			||||||
	strlcpy(root->release_agent_path, buffer,
 | 
						strlcpy(root->release_agent_path, strstrip(buf),
 | 
				
			||||||
		sizeof(root->release_agent_path));
 | 
							sizeof(root->release_agent_path));
 | 
				
			||||||
	spin_unlock(&release_agent_path_lock);
 | 
						spin_unlock(&release_agent_path_lock);
 | 
				
			||||||
	mutex_unlock(&cgroup_mutex);
 | 
						mutex_unlock(&cgroup_mutex);
 | 
				
			||||||
	return 0;
 | 
						return nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cgroup_release_agent_show(struct seq_file *seq, void *v)
 | 
					static int cgroup_release_agent_show(struct seq_file *seq, void *v)
 | 
				
			||||||
| 
						 | 
					@ -2530,21 +2531,22 @@ out_finish:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* change the enabled child controllers for a cgroup in the default hierarchy */
 | 
					/* change the enabled child controllers for a cgroup in the default hierarchy */
 | 
				
			||||||
static int cgroup_subtree_control_write(struct cgroup_subsys_state *dummy_css,
 | 
					static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
 | 
				
			||||||
					struct cftype *cft, char *buffer)
 | 
										    char *buf, size_t nbytes,
 | 
				
			||||||
 | 
										    loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int enable = 0, disable = 0;
 | 
						unsigned int enable = 0, disable = 0;
 | 
				
			||||||
	struct cgroup *cgrp = dummy_css->cgroup, *child;
 | 
						struct cgroup *cgrp = of_css(of)->cgroup, *child;
 | 
				
			||||||
	struct cgroup_subsys *ss;
 | 
						struct cgroup_subsys *ss;
 | 
				
			||||||
	char *tok, *p;
 | 
						char *tok;
 | 
				
			||||||
	int ssid, ret;
 | 
						int ssid, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Parse input - space separated list of subsystem names prefixed
 | 
						 * Parse input - space separated list of subsystem names prefixed
 | 
				
			||||||
	 * with either + or -.
 | 
						 * with either + or -.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	p = buffer;
 | 
						buf = strstrip(buf);
 | 
				
			||||||
	while ((tok = strsep(&p, " "))) {
 | 
						while ((tok = strsep(&buf, " "))) {
 | 
				
			||||||
		if (tok[0] == '\0')
 | 
							if (tok[0] == '\0')
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		for_each_subsys(ss, ssid) {
 | 
							for_each_subsys(ss, ssid) {
 | 
				
			||||||
| 
						 | 
					@ -2692,7 +2694,7 @@ out_unlock_tree:
 | 
				
			||||||
out_unbreak:
 | 
					out_unbreak:
 | 
				
			||||||
	kernfs_unbreak_active_protection(cgrp->control_kn);
 | 
						kernfs_unbreak_active_protection(cgrp->control_kn);
 | 
				
			||||||
	cgroup_put(cgrp);
 | 
						cgroup_put(cgrp);
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_undo_css:
 | 
					err_undo_css:
 | 
				
			||||||
	cgrp->child_subsys_mask &= ~enable;
 | 
						cgrp->child_subsys_mask &= ~enable;
 | 
				
			||||||
| 
						 | 
					@ -2738,9 +2740,7 @@ static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf,
 | 
				
			||||||
	css = cgroup_css(cgrp, cft->ss);
 | 
						css = cgroup_css(cgrp, cft->ss);
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cft->write_string) {
 | 
						if (cft->write_u64) {
 | 
				
			||||||
		ret = cft->write_string(css, cft, strstrip(buf));
 | 
					 | 
				
			||||||
	} else if (cft->write_u64) {
 | 
					 | 
				
			||||||
		unsigned long long v;
 | 
							unsigned long long v;
 | 
				
			||||||
		ret = kstrtoull(buf, 0, &v);
 | 
							ret = kstrtoull(buf, 0, &v);
 | 
				
			||||||
		if (!ret)
 | 
							if (!ret)
 | 
				
			||||||
| 
						 | 
					@ -3984,7 +3984,7 @@ static struct cftype cgroup_base_files[] = {
 | 
				
			||||||
		.name = "cgroup.subtree_control",
 | 
							.name = "cgroup.subtree_control",
 | 
				
			||||||
		.flags = CFTYPE_ONLY_ON_DFL,
 | 
							.flags = CFTYPE_ONLY_ON_DFL,
 | 
				
			||||||
		.seq_show = cgroup_subtree_control_show,
 | 
							.seq_show = cgroup_subtree_control_show,
 | 
				
			||||||
		.write_string = cgroup_subtree_control_write,
 | 
							.write = cgroup_subtree_control_write,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "cgroup.populated",
 | 
							.name = "cgroup.populated",
 | 
				
			||||||
| 
						 | 
					@ -4018,7 +4018,7 @@ static struct cftype cgroup_base_files[] = {
 | 
				
			||||||
		.name = "release_agent",
 | 
							.name = "release_agent",
 | 
				
			||||||
		.flags = CFTYPE_INSANE | CFTYPE_ONLY_ON_ROOT,
 | 
							.flags = CFTYPE_INSANE | CFTYPE_ONLY_ON_ROOT,
 | 
				
			||||||
		.seq_show = cgroup_release_agent_show,
 | 
							.seq_show = cgroup_release_agent_show,
 | 
				
			||||||
		.write_string = cgroup_release_agent_write,
 | 
							.write = cgroup_release_agent_write,
 | 
				
			||||||
		.max_write_len = PATH_MAX - 1,
 | 
							.max_write_len = PATH_MAX - 1,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{ }	/* terminate */
 | 
						{ }	/* terminate */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,10 +73,6 @@ bool cgroup_freezing(struct task_struct *task)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * cgroups_write_string() limits the size of freezer state strings to
 | 
					 | 
				
			||||||
 * CGROUP_LOCAL_BUFFER_SIZE
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const char *freezer_state_strs(unsigned int state)
 | 
					static const char *freezer_state_strs(unsigned int state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (state & CGROUP_FROZEN)
 | 
						if (state & CGROUP_FROZEN)
 | 
				
			||||||
| 
						 | 
					@ -423,20 +419,22 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
 | 
				
			||||||
	mutex_unlock(&freezer_mutex);
 | 
						mutex_unlock(&freezer_mutex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int freezer_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t freezer_write(struct kernfs_open_file *of,
 | 
				
			||||||
			 char *buffer)
 | 
								     char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool freeze;
 | 
						bool freeze;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (strcmp(buffer, freezer_state_strs(0)) == 0)
 | 
						buf = strstrip(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(buf, freezer_state_strs(0)) == 0)
 | 
				
			||||||
		freeze = false;
 | 
							freeze = false;
 | 
				
			||||||
	else if (strcmp(buffer, freezer_state_strs(CGROUP_FROZEN)) == 0)
 | 
						else if (strcmp(buf, freezer_state_strs(CGROUP_FROZEN)) == 0)
 | 
				
			||||||
		freeze = true;
 | 
							freeze = true;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	freezer_change_state(css_freezer(css), freeze);
 | 
						freezer_change_state(css_freezer(of_css(of)), freeze);
 | 
				
			||||||
	return 0;
 | 
						return nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u64 freezer_self_freezing_read(struct cgroup_subsys_state *css,
 | 
					static u64 freezer_self_freezing_read(struct cgroup_subsys_state *css,
 | 
				
			||||||
| 
						 | 
					@ -460,7 +458,7 @@ static struct cftype files[] = {
 | 
				
			||||||
		.name = "state",
 | 
							.name = "state",
 | 
				
			||||||
		.flags = CFTYPE_NOT_ON_ROOT,
 | 
							.flags = CFTYPE_NOT_ON_ROOT,
 | 
				
			||||||
		.seq_show = freezer_read,
 | 
							.seq_show = freezer_read,
 | 
				
			||||||
		.write_string = freezer_write,
 | 
							.write = freezer_write,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "self_freezing",
 | 
							.name = "self_freezing",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1603,13 +1603,15 @@ out_unlock:
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Common handling for a write to a "cpus" or "mems" file.
 | 
					 * Common handling for a write to a "cpus" or "mems" file.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int cpuset_write_resmask(struct cgroup_subsys_state *css,
 | 
					static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
 | 
				
			||||||
				struct cftype *cft, char *buf)
 | 
									    char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cpuset *cs = css_cs(css);
 | 
						struct cpuset *cs = css_cs(of_css(of));
 | 
				
			||||||
	struct cpuset *trialcs;
 | 
						struct cpuset *trialcs;
 | 
				
			||||||
	int retval = -ENODEV;
 | 
						int retval = -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf = strstrip(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * CPU or memory hotunplug may leave @cs w/o any execution
 | 
						 * CPU or memory hotunplug may leave @cs w/o any execution
 | 
				
			||||||
	 * resources, in which case the hotplug code asynchronously updates
 | 
						 * resources, in which case the hotplug code asynchronously updates
 | 
				
			||||||
| 
						 | 
					@ -1633,7 +1635,7 @@ static int cpuset_write_resmask(struct cgroup_subsys_state *css,
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cft->private) {
 | 
						switch (of_cft(of)->private) {
 | 
				
			||||||
	case FILE_CPULIST:
 | 
						case FILE_CPULIST:
 | 
				
			||||||
		retval = update_cpumask(cs, trialcs, buf);
 | 
							retval = update_cpumask(cs, trialcs, buf);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -1648,7 +1650,7 @@ static int cpuset_write_resmask(struct cgroup_subsys_state *css,
 | 
				
			||||||
	free_trial_cpuset(trialcs);
 | 
						free_trial_cpuset(trialcs);
 | 
				
			||||||
out_unlock:
 | 
					out_unlock:
 | 
				
			||||||
	mutex_unlock(&cpuset_mutex);
 | 
						mutex_unlock(&cpuset_mutex);
 | 
				
			||||||
	return retval;
 | 
						return retval ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1750,7 +1752,7 @@ static struct cftype files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "cpus",
 | 
							.name = "cpus",
 | 
				
			||||||
		.seq_show = cpuset_common_seq_show,
 | 
							.seq_show = cpuset_common_seq_show,
 | 
				
			||||||
		.write_string = cpuset_write_resmask,
 | 
							.write = cpuset_write_resmask,
 | 
				
			||||||
		.max_write_len = (100U + 6 * NR_CPUS),
 | 
							.max_write_len = (100U + 6 * NR_CPUS),
 | 
				
			||||||
		.private = FILE_CPULIST,
 | 
							.private = FILE_CPULIST,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -1758,7 +1760,7 @@ static struct cftype files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "mems",
 | 
							.name = "mems",
 | 
				
			||||||
		.seq_show = cpuset_common_seq_show,
 | 
							.seq_show = cpuset_common_seq_show,
 | 
				
			||||||
		.write_string = cpuset_write_resmask,
 | 
							.write = cpuset_write_resmask,
 | 
				
			||||||
		.max_write_len = (100U + 6 * MAX_NUMNODES),
 | 
							.max_write_len = (100U + 6 * MAX_NUMNODES),
 | 
				
			||||||
		.private = FILE_MEMLIST,
 | 
							.private = FILE_MEMLIST,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,15 +253,16 @@ static u64 hugetlb_cgroup_read_u64(struct cgroup_subsys_state *css,
 | 
				
			||||||
	return res_counter_read_u64(&h_cg->hugepage[idx], name);
 | 
						return res_counter_read_u64(&h_cg->hugepage[idx], name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hugetlb_cgroup_write(struct cgroup_subsys_state *css,
 | 
					static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of,
 | 
				
			||||||
				struct cftype *cft, char *buffer)
 | 
									    char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int idx, name, ret;
 | 
						int idx, name, ret;
 | 
				
			||||||
	unsigned long long val;
 | 
						unsigned long long val;
 | 
				
			||||||
	struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css);
 | 
						struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(of_css(of));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idx = MEMFILE_IDX(cft->private);
 | 
						buf = strstrip(buf);
 | 
				
			||||||
	name = MEMFILE_ATTR(cft->private);
 | 
						idx = MEMFILE_IDX(of_cft(of)->private);
 | 
				
			||||||
 | 
						name = MEMFILE_ATTR(of_cft(of)->private);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (name) {
 | 
						switch (name) {
 | 
				
			||||||
	case RES_LIMIT:
 | 
						case RES_LIMIT:
 | 
				
			||||||
| 
						 | 
					@ -271,7 +272,7 @@ static int hugetlb_cgroup_write(struct cgroup_subsys_state *css,
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/* This function does all necessary parse...reuse it */
 | 
							/* This function does all necessary parse...reuse it */
 | 
				
			||||||
		ret = res_counter_memparse_write_strategy(buffer, &val);
 | 
							ret = res_counter_memparse_write_strategy(buf, &val);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		ret = res_counter_set_limit(&h_cg->hugepage[idx], val);
 | 
							ret = res_counter_set_limit(&h_cg->hugepage[idx], val);
 | 
				
			||||||
| 
						 | 
					@ -280,7 +281,7 @@ static int hugetlb_cgroup_write(struct cgroup_subsys_state *css,
 | 
				
			||||||
		ret = -EINVAL;
 | 
							ret = -EINVAL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hugetlb_cgroup_reset(struct cgroup_subsys_state *css,
 | 
					static int hugetlb_cgroup_reset(struct cgroup_subsys_state *css,
 | 
				
			||||||
| 
						 | 
					@ -331,7 +332,7 @@ static void __init __hugetlb_cgroup_file_init(int idx)
 | 
				
			||||||
	snprintf(cft->name, MAX_CFTYPE_NAME, "%s.limit_in_bytes", buf);
 | 
						snprintf(cft->name, MAX_CFTYPE_NAME, "%s.limit_in_bytes", buf);
 | 
				
			||||||
	cft->private = MEMFILE_PRIVATE(idx, RES_LIMIT);
 | 
						cft->private = MEMFILE_PRIVATE(idx, RES_LIMIT);
 | 
				
			||||||
	cft->read_u64 = hugetlb_cgroup_read_u64;
 | 
						cft->read_u64 = hugetlb_cgroup_read_u64;
 | 
				
			||||||
	cft->write_string = hugetlb_cgroup_write;
 | 
						cft->write = hugetlb_cgroup_write;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Add the usage file */
 | 
						/* Add the usage file */
 | 
				
			||||||
	cft = &h->cgroup_files[1];
 | 
						cft = &h->cgroup_files[1];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5143,17 +5143,18 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
 | 
				
			||||||
 * The user of this function is...
 | 
					 * The user of this function is...
 | 
				
			||||||
 * RES_LIMIT.
 | 
					 * RES_LIMIT.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t mem_cgroup_write(struct kernfs_open_file *of,
 | 
				
			||||||
			    char *buffer)
 | 
									char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 | 
						struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
 | 
				
			||||||
	enum res_type type;
 | 
						enum res_type type;
 | 
				
			||||||
	int name;
 | 
						int name;
 | 
				
			||||||
	unsigned long long val;
 | 
						unsigned long long val;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type = MEMFILE_TYPE(cft->private);
 | 
						buf = strstrip(buf);
 | 
				
			||||||
	name = MEMFILE_ATTR(cft->private);
 | 
						type = MEMFILE_TYPE(of_cft(of)->private);
 | 
				
			||||||
 | 
						name = MEMFILE_ATTR(of_cft(of)->private);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (name) {
 | 
						switch (name) {
 | 
				
			||||||
	case RES_LIMIT:
 | 
						case RES_LIMIT:
 | 
				
			||||||
| 
						 | 
					@ -5162,7 +5163,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/* This function does all necessary parse...reuse it */
 | 
							/* This function does all necessary parse...reuse it */
 | 
				
			||||||
		ret = res_counter_memparse_write_strategy(buffer, &val);
 | 
							ret = res_counter_memparse_write_strategy(buf, &val);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (type == _MEM)
 | 
							if (type == _MEM)
 | 
				
			||||||
| 
						 | 
					@ -5175,7 +5176,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case RES_SOFT_LIMIT:
 | 
						case RES_SOFT_LIMIT:
 | 
				
			||||||
		ret = res_counter_memparse_write_strategy(buffer, &val);
 | 
							ret = res_counter_memparse_write_strategy(buf, &val);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -5192,7 +5193,7 @@ static int mem_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
		ret = -EINVAL; /* should be BUG() ? */
 | 
							ret = -EINVAL; /* should be BUG() ? */
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,
 | 
					static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,
 | 
				
			||||||
| 
						 | 
					@ -5964,9 +5965,10 @@ static void memcg_event_ptable_queue_proc(struct file *file,
 | 
				
			||||||
 * Input must be in format '<event_fd> <control_fd> <args>'.
 | 
					 * Input must be in format '<event_fd> <control_fd> <args>'.
 | 
				
			||||||
 * Interpretation of args is defined by control file implementation.
 | 
					 * Interpretation of args is defined by control file implementation.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int memcg_write_event_control(struct cgroup_subsys_state *css,
 | 
					static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
 | 
				
			||||||
				     struct cftype *cft, char *buffer)
 | 
										 char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct cgroup_subsys_state *css = of_css(of);
 | 
				
			||||||
	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 | 
						struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 | 
				
			||||||
	struct mem_cgroup_event *event;
 | 
						struct mem_cgroup_event *event;
 | 
				
			||||||
	struct cgroup_subsys_state *cfile_css;
 | 
						struct cgroup_subsys_state *cfile_css;
 | 
				
			||||||
| 
						 | 
					@ -5977,15 +5979,17 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
 | 
				
			||||||
	char *endp;
 | 
						char *endp;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efd = simple_strtoul(buffer, &endp, 10);
 | 
						buf = strstrip(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						efd = simple_strtoul(buf, &endp, 10);
 | 
				
			||||||
	if (*endp != ' ')
 | 
						if (*endp != ' ')
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	buffer = endp + 1;
 | 
						buf = endp + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfd = simple_strtoul(buffer, &endp, 10);
 | 
						cfd = simple_strtoul(buf, &endp, 10);
 | 
				
			||||||
	if ((*endp != ' ') && (*endp != '\0'))
 | 
						if ((*endp != ' ') && (*endp != '\0'))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	buffer = endp + 1;
 | 
						buf = endp + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	event = kzalloc(sizeof(*event), GFP_KERNEL);
 | 
						event = kzalloc(sizeof(*event), GFP_KERNEL);
 | 
				
			||||||
	if (!event)
 | 
						if (!event)
 | 
				
			||||||
| 
						 | 
					@ -6063,7 +6067,7 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
 | 
				
			||||||
		goto out_put_cfile;
 | 
							goto out_put_cfile;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = event->register_event(memcg, event->eventfd, buffer);
 | 
						ret = event->register_event(memcg, event->eventfd, buf);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out_put_css;
 | 
							goto out_put_css;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6076,7 +6080,7 @@ static int memcg_write_event_control(struct cgroup_subsys_state *css,
 | 
				
			||||||
	fdput(cfile);
 | 
						fdput(cfile);
 | 
				
			||||||
	fdput(efile);
 | 
						fdput(efile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return nbytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_put_css:
 | 
					out_put_css:
 | 
				
			||||||
	css_put(css);
 | 
						css_put(css);
 | 
				
			||||||
| 
						 | 
					@ -6107,13 +6111,13 @@ static struct cftype mem_cgroup_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "limit_in_bytes",
 | 
							.name = "limit_in_bytes",
 | 
				
			||||||
		.private = MEMFILE_PRIVATE(_MEM, RES_LIMIT),
 | 
							.private = MEMFILE_PRIVATE(_MEM, RES_LIMIT),
 | 
				
			||||||
		.write_string = mem_cgroup_write,
 | 
							.write = mem_cgroup_write,
 | 
				
			||||||
		.read_u64 = mem_cgroup_read_u64,
 | 
							.read_u64 = mem_cgroup_read_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "soft_limit_in_bytes",
 | 
							.name = "soft_limit_in_bytes",
 | 
				
			||||||
		.private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
 | 
							.private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT),
 | 
				
			||||||
		.write_string = mem_cgroup_write,
 | 
							.write = mem_cgroup_write,
 | 
				
			||||||
		.read_u64 = mem_cgroup_read_u64,
 | 
							.read_u64 = mem_cgroup_read_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -6138,7 +6142,7 @@ static struct cftype mem_cgroup_files[] = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "cgroup.event_control",		/* XXX: for compat */
 | 
							.name = "cgroup.event_control",		/* XXX: for compat */
 | 
				
			||||||
		.write_string = memcg_write_event_control,
 | 
							.write = memcg_write_event_control,
 | 
				
			||||||
		.flags = CFTYPE_NO_PREFIX,
 | 
							.flags = CFTYPE_NO_PREFIX,
 | 
				
			||||||
		.mode = S_IWUGO,
 | 
							.mode = S_IWUGO,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -6171,7 +6175,7 @@ static struct cftype mem_cgroup_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "kmem.limit_in_bytes",
 | 
							.name = "kmem.limit_in_bytes",
 | 
				
			||||||
		.private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT),
 | 
							.private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT),
 | 
				
			||||||
		.write_string = mem_cgroup_write,
 | 
							.write = mem_cgroup_write,
 | 
				
			||||||
		.read_u64 = mem_cgroup_read_u64,
 | 
							.read_u64 = mem_cgroup_read_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -6217,7 +6221,7 @@ static struct cftype memsw_cgroup_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "memsw.limit_in_bytes",
 | 
							.name = "memsw.limit_in_bytes",
 | 
				
			||||||
		.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
 | 
							.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
 | 
				
			||||||
		.write_string = mem_cgroup_write,
 | 
							.write = mem_cgroup_write,
 | 
				
			||||||
		.read_u64 = mem_cgroup_read_u64,
 | 
							.read_u64 = mem_cgroup_read_u64,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -185,15 +185,15 @@ static int read_priomap(struct seq_file *sf, void *v)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int write_priomap(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t write_priomap(struct kernfs_open_file *of,
 | 
				
			||||||
			 char *buffer)
 | 
								     char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char devname[IFNAMSIZ + 1];
 | 
						char devname[IFNAMSIZ + 1];
 | 
				
			||||||
	struct net_device *dev;
 | 
						struct net_device *dev;
 | 
				
			||||||
	u32 prio;
 | 
						u32 prio;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sscanf(buffer, "%"__stringify(IFNAMSIZ)"s %u", devname, &prio) != 2)
 | 
						if (sscanf(buf, "%"__stringify(IFNAMSIZ)"s %u", devname, &prio) != 2)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev = dev_get_by_name(&init_net, devname);
 | 
						dev = dev_get_by_name(&init_net, devname);
 | 
				
			||||||
| 
						 | 
					@ -202,11 +202,11 @@ static int write_priomap(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_lock();
 | 
						rtnl_lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = netprio_set_prio(css, dev, prio);
 | 
						ret = netprio_set_prio(of_css(of), dev, prio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
	dev_put(dev);
 | 
						dev_put(dev);
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int update_netprio(const void *v, struct file *file, unsigned n)
 | 
					static int update_netprio(const void *v, struct file *file, unsigned n)
 | 
				
			||||||
| 
						 | 
					@ -239,7 +239,7 @@ static struct cftype ss_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "ifpriomap",
 | 
							.name = "ifpriomap",
 | 
				
			||||||
		.seq_show = read_priomap,
 | 
							.seq_show = read_priomap,
 | 
				
			||||||
		.write_string = write_priomap,
 | 
							.write = write_priomap,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{ }	/* terminate */
 | 
						{ }	/* terminate */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,17 +102,19 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tcp_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
					static ssize_t tcp_cgroup_write(struct kernfs_open_file *of,
 | 
				
			||||||
			    char *buffer)
 | 
									char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mem_cgroup *memcg = mem_cgroup_from_css(css);
 | 
						struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
 | 
				
			||||||
	unsigned long long val;
 | 
						unsigned long long val;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cft->private) {
 | 
						buf = strstrip(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (of_cft(of)->private) {
 | 
				
			||||||
	case RES_LIMIT:
 | 
						case RES_LIMIT:
 | 
				
			||||||
		/* see memcontrol.c */
 | 
							/* see memcontrol.c */
 | 
				
			||||||
		ret = res_counter_memparse_write_strategy(buffer, &val);
 | 
							ret = res_counter_memparse_write_strategy(buf, &val);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		ret = tcp_update_limit(memcg, val);
 | 
							ret = tcp_update_limit(memcg, val);
 | 
				
			||||||
| 
						 | 
					@ -121,7 +123,7 @@ static int tcp_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
 | 
				
			||||||
		ret = -EINVAL;
 | 
							ret = -EINVAL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret;
 | 
						return ret ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val)
 | 
					static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val)
 | 
				
			||||||
| 
						 | 
					@ -193,7 +195,7 @@ static int tcp_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event)
 | 
				
			||||||
static struct cftype tcp_files[] = {
 | 
					static struct cftype tcp_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "kmem.tcp.limit_in_bytes",
 | 
							.name = "kmem.tcp.limit_in_bytes",
 | 
				
			||||||
		.write_string = tcp_cgroup_write,
 | 
							.write = tcp_cgroup_write,
 | 
				
			||||||
		.read_u64 = tcp_cgroup_read,
 | 
							.read_u64 = tcp_cgroup_read,
 | 
				
			||||||
		.private = RES_LIMIT,
 | 
							.private = RES_LIMIT,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -767,27 +767,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int devcgroup_access_write(struct cgroup_subsys_state *css,
 | 
					static ssize_t devcgroup_access_write(struct kernfs_open_file *of,
 | 
				
			||||||
				  struct cftype *cft, char *buffer)
 | 
									      char *buf, size_t nbytes, loff_t off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retval;
 | 
						int retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&devcgroup_mutex);
 | 
						mutex_lock(&devcgroup_mutex);
 | 
				
			||||||
	retval = devcgroup_update_access(css_to_devcgroup(css),
 | 
						retval = devcgroup_update_access(css_to_devcgroup(of_css(of)),
 | 
				
			||||||
					 cft->private, buffer);
 | 
										 of_cft(of)->private, strstrip(buf));
 | 
				
			||||||
	mutex_unlock(&devcgroup_mutex);
 | 
						mutex_unlock(&devcgroup_mutex);
 | 
				
			||||||
	return retval;
 | 
						return retval ?: nbytes;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct cftype dev_cgroup_files[] = {
 | 
					static struct cftype dev_cgroup_files[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "allow",
 | 
							.name = "allow",
 | 
				
			||||||
		.write_string  = devcgroup_access_write,
 | 
							.write = devcgroup_access_write,
 | 
				
			||||||
		.private = DEVCG_ALLOW,
 | 
							.private = DEVCG_ALLOW,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "deny",
 | 
							.name = "deny",
 | 
				
			||||||
		.write_string = devcgroup_access_write,
 | 
							.write = devcgroup_access_write,
 | 
				
			||||||
		.private = DEVCG_DENY,
 | 
							.private = DEVCG_DENY,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue