Skip to content

Commit

Permalink
cgroup: replace cftype->write_string() with cftype->write()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Aristeu Rozanski <[email protected]>
Acked-by: Vivek Goyal <[email protected]>
Acked-by: Li Zefan <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Neil Horman <[email protected]>
Cc: "David S. Miller" <[email protected]>
  • Loading branch information
htejun committed May 13, 2014
1 parent b416864 commit 451af50
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 125 deletions.
32 changes: 16 additions & 16 deletions block/blk-throttle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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",
Expand Down Expand Up @@ -1404,45 +1404,45 @@ 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[] = {
{
.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",
Expand Down
28 changes: 14 additions & 14 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
bool is_leaf_weight)
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;
Expand All @@ -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,
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand Down
10 changes: 1 addition & 9 deletions include/linux/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
38 changes: 19 additions & 19 deletions kernel/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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 */
Expand Down
20 changes: 9 additions & 11 deletions kernel/cgroup_freezer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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",
Expand Down
16 changes: 9 additions & 7 deletions kernel/cpuset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1603,13 +1603,15 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
/*
* Common handling for a write to a "cpus" or "mems" file.
*/
static int cpuset_write_resmask(struct cgroup_subsys_state *css,
struct cftype *cft, char *buf)
static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
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;
int retval = -ENODEV;

buf = strstrip(buf);

/*
* CPU or memory hotunplug may leave @cs w/o any execution
* resources, in which case the hotplug code asynchronously updates
Expand All @@ -1633,7 +1635,7 @@ static int cpuset_write_resmask(struct cgroup_subsys_state *css,
goto out_unlock;
}

switch (cft->private) {
switch (of_cft(of)->private) {
case FILE_CPULIST:
retval = update_cpumask(cs, trialcs, buf);
break;
Expand All @@ -1648,7 +1650,7 @@ static int cpuset_write_resmask(struct cgroup_subsys_state *css,
free_trial_cpuset(trialcs);
out_unlock:
mutex_unlock(&cpuset_mutex);
return retval;
return retval ?: nbytes;
}

/*
Expand Down Expand Up @@ -1750,15 +1752,15 @@ static struct cftype files[] = {
{
.name = "cpus",
.seq_show = cpuset_common_seq_show,
.write_string = cpuset_write_resmask,
.write = cpuset_write_resmask,
.max_write_len = (100U + 6 * NR_CPUS),
.private = FILE_CPULIST,
},

{
.name = "mems",
.seq_show = cpuset_common_seq_show,
.write_string = cpuset_write_resmask,
.write = cpuset_write_resmask,
.max_write_len = (100U + 6 * MAX_NUMNODES),
.private = FILE_MEMLIST,
},
Expand Down
Loading

0 comments on commit 451af50

Please sign in to comment.