Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 451af504 authored by Tejun Heo's avatar Tejun Heo
Browse files

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: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarAristeu Rozanski <arozansk@redhat.com>
Acked-by: default avatarVivek Goyal <vgoyal@redhat.com>
Acked-by: default avatarLi 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>
parent b4168640
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -1346,10 +1346,10 @@ static int tg_print_conf_uint(struct seq_file *sf, void *v)
	return 0;
}

static int tg_set_conf(struct cgroup_subsys_state *css, struct cftype *cft,
		       const char *buf, bool is_u64)
static ssize_t tg_set_conf(struct kernfs_open_file *of,
			   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 throtl_grp *tg;
	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;

	if (is_u64)
		*(u64 *)((void *)tg + cft->private) = ctx.v;
		*(u64 *)((void *)tg + of_cft(of)->private) = ctx.v;
	else
		*(unsigned int *)((void *)tg + cft->private) = ctx.v;
		*(unsigned int *)((void *)tg + of_cft(of)->private) = ctx.v;

	throtl_log(&tg->service_queue,
		   "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);
	return 0;
	return nbytes;
}

static int tg_set_conf_u64(struct cgroup_subsys_state *css, struct cftype *cft,
			   char *buf)
static ssize_t tg_set_conf_u64(struct kernfs_open_file *of,
			       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,
			    char *buf)
static ssize_t tg_set_conf_uint(struct kernfs_open_file *of,
				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[] = {
@@ -1424,25 +1424,25 @@ static struct cftype throtl_files[] = {
		.name = "throttle.read_bps_device",
		.private = offsetof(struct throtl_grp, bps[READ]),
		.seq_show = tg_print_conf_u64,
		.write_string = tg_set_conf_u64,
		.write = tg_set_conf_u64,
	},
	{
		.name = "throttle.write_bps_device",
		.private = offsetof(struct throtl_grp, bps[WRITE]),
		.seq_show = tg_print_conf_u64,
		.write_string = tg_set_conf_u64,
		.write = tg_set_conf_u64,
	},
	{
		.name = "throttle.read_iops_device",
		.private = offsetof(struct throtl_grp, iops[READ]),
		.seq_show = tg_print_conf_uint,
		.write_string = tg_set_conf_uint,
		.write = tg_set_conf_uint,
	},
	{
		.name = "throttle.write_iops_device",
		.private = offsetof(struct throtl_grp, iops[WRITE]),
		.seq_show = tg_print_conf_uint,
		.write_string = tg_set_conf_uint,
		.write = tg_set_conf_uint,
	},
	{
		.name = "throttle.io_service_bytes",
+14 −14
Original line number Diff line number Diff line
@@ -1670,11 +1670,11 @@ static int cfq_print_leaf_weight(struct seq_file *sf, void *v)
	return 0;
}

static int __cfqg_set_weight_device(struct cgroup_subsys_state *css,
				    struct cftype *cft, const char *buf,
static ssize_t __cfqg_set_weight_device(struct kernfs_open_file *of,
					char *buf, size_t nbytes, loff_t off,
					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 cfq_group *cfqg;
	int ret;
@@ -1697,19 +1697,19 @@ static int __cfqg_set_weight_device(struct cgroup_subsys_state *css,
	}

	blkg_conf_finish(&ctx);
	return ret;
	return ret ?: nbytes;
}

static int cfqg_set_weight_device(struct cgroup_subsys_state *css,
				  struct cftype *cft, char *buf)
static ssize_t cfqg_set_weight_device(struct kernfs_open_file *of,
				      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,
				       struct cftype *cft, char *buf)
static ssize_t cfqg_set_leaf_weight_device(struct kernfs_open_file *of,
					   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,
@@ -1837,7 +1837,7 @@ static struct cftype cfq_blkcg_files[] = {
		.name = "weight_device",
		.flags = CFTYPE_ONLY_ON_ROOT,
		.seq_show = cfqg_print_leaf_weight_device,
		.write_string = cfqg_set_leaf_weight_device,
		.write = cfqg_set_leaf_weight_device,
	},
	{
		.name = "weight",
@@ -1851,7 +1851,7 @@ static struct cftype cfq_blkcg_files[] = {
		.name = "weight_device",
		.flags = CFTYPE_NOT_ON_ROOT,
		.seq_show = cfqg_print_weight_device,
		.write_string = cfqg_set_weight_device,
		.write = cfqg_set_weight_device,
	},
	{
		.name = "weight",
@@ -1863,7 +1863,7 @@ static struct cftype cfq_blkcg_files[] = {
	{
		.name = "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",
+1 −9
Original line number Diff line number Diff line
@@ -453,8 +453,7 @@ struct cftype {

	/*
	 * The maximum length of string, excluding trailing nul, that can
	 * be passed to write_string.  If < PAGE_SIZE-1, PAGE_SIZE-1 is
	 * assumed.
	 * be passed to write.  If < PAGE_SIZE-1, PAGE_SIZE-1 is assumed.
	 */
	size_t max_write_len;

@@ -500,13 +499,6 @@ struct cftype {
	int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft,
			 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
	 * userspace, when the actual string written is not important
+19 −19
Original line number Diff line number Diff line
@@ -1035,7 +1035,7 @@ static umode_t cgroup_file_mode(const struct cftype *cft)
		mode |= S_IRUGO;

	if (cft->write_u64 || cft->write_s64 || cft->write ||
	    cft->write_string || cft->trigger)
	    cft->trigger)
		mode |= S_IWUSR;

	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);
}

static int cgroup_release_agent_write(struct cgroup_subsys_state *css,
				      struct cftype *cft, char *buffer)
static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of,
					  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);
	if (!cgroup_lock_live_group(css->cgroup))
	if (!cgroup_lock_live_group(cgrp))
		return -ENODEV;
	spin_lock(&release_agent_path_lock);
	strlcpy(root->release_agent_path, buffer,
	strlcpy(root->release_agent_path, strstrip(buf),
		sizeof(root->release_agent_path));
	spin_unlock(&release_agent_path_lock);
	mutex_unlock(&cgroup_mutex);
	return 0;
	return nbytes;
}

static int cgroup_release_agent_show(struct seq_file *seq, void *v)
@@ -2530,21 +2531,22 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
}

/* change the enabled child controllers for a cgroup in the default hierarchy */
static int cgroup_subtree_control_write(struct cgroup_subsys_state *dummy_css,
					struct cftype *cft, char *buffer)
static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
					    char *buf, size_t nbytes,
					    loff_t off)
{
	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;
	char *tok, *p;
	char *tok;
	int ssid, ret;

	/*
	 * Parse input - space separated list of subsystem names prefixed
	 * with either + or -.
	 */
	p = buffer;
	while ((tok = strsep(&p, " "))) {
	buf = strstrip(buf);
	while ((tok = strsep(&buf, " "))) {
		if (tok[0] == '\0')
			continue;
		for_each_subsys(ss, ssid) {
@@ -2692,7 +2694,7 @@ static int cgroup_subtree_control_write(struct cgroup_subsys_state *dummy_css,
out_unbreak:
	kernfs_unbreak_active_protection(cgrp->control_kn);
	cgroup_put(cgrp);
	return ret;
	return ret ?: nbytes;

err_undo_css:
	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);
	rcu_read_unlock();

	if (cft->write_string) {
		ret = cft->write_string(css, cft, strstrip(buf));
	} else if (cft->write_u64) {
	if (cft->write_u64) {
		unsigned long long v;
		ret = kstrtoull(buf, 0, &v);
		if (!ret)
@@ -3984,7 +3984,7 @@ static struct cftype cgroup_base_files[] = {
		.name = "cgroup.subtree_control",
		.flags = CFTYPE_ONLY_ON_DFL,
		.seq_show = cgroup_subtree_control_show,
		.write_string = cgroup_subtree_control_write,
		.write = cgroup_subtree_control_write,
	},
	{
		.name = "cgroup.populated",
@@ -4018,7 +4018,7 @@ static struct cftype cgroup_base_files[] = {
		.name = "release_agent",
		.flags = CFTYPE_INSANE | CFTYPE_ONLY_ON_ROOT,
		.seq_show = cgroup_release_agent_show,
		.write_string = cgroup_release_agent_write,
		.write = cgroup_release_agent_write,
		.max_write_len = PATH_MAX - 1,
	},
	{ }	/* terminate */
+9 −11
Original line number Diff line number Diff line
@@ -73,10 +73,6 @@ bool cgroup_freezing(struct task_struct *task)
	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)
{
	if (state & CGROUP_FROZEN)
@@ -423,20 +419,22 @@ static void freezer_change_state(struct freezer *freezer, bool freeze)
	mutex_unlock(&freezer_mutex);
}

static int freezer_write(struct cgroup_subsys_state *css, struct cftype *cft,
			 char *buffer)
static ssize_t freezer_write(struct kernfs_open_file *of,
			     char *buf, size_t nbytes, loff_t off)
{
	bool freeze;

	if (strcmp(buffer, freezer_state_strs(0)) == 0)
	buf = strstrip(buf);

	if (strcmp(buf, freezer_state_strs(0)) == 0)
		freeze = false;
	else if (strcmp(buffer, freezer_state_strs(CGROUP_FROZEN)) == 0)
	else if (strcmp(buf, freezer_state_strs(CGROUP_FROZEN)) == 0)
		freeze = true;
	else
		return -EINVAL;

	freezer_change_state(css_freezer(css), freeze);
	return 0;
	freezer_change_state(css_freezer(of_css(of)), freeze);
	return nbytes;
}

static u64 freezer_self_freezing_read(struct cgroup_subsys_state *css,
@@ -460,7 +458,7 @@ static struct cftype files[] = {
		.name = "state",
		.flags = CFTYPE_NOT_ON_ROOT,
		.seq_show = freezer_read,
		.write_string = freezer_write,
		.write = freezer_write,
	},
	{
		.name = "self_freezing",
Loading