diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-11 11:52:48 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-11 11:52:48 -0500 |
commit | 5f46990787e2721b4db190ddc8af6fdbe8f010d7 (patch) | |
tree | 5a5e8439e8560eb95a86f58036b5282e1a7036b6 /kernel/cgroup.c | |
parent | de00ffa56ea3132c6013fc8f07133b8a1014cf53 (diff) |
cgroup: update the meaning of cftype->max_write_len
cftype->max_write_len is used to extend the maximum size of writes.
It's interpreted in such a way that the actual maximum size is one
less than the specified value. The default size is defined by
CGROUP_LOCAL_BUFFER_SIZE. Its interpretation is quite confusing - its
value is decremented by 1 and then compared for equality with max
size, which means that the actual default size is
CGROUP_LOCAL_BUFFER_SIZE - 2, which is 62 chars.
There's no point in having a limit that low. Update its definition so
that it means the actual string length sans termination and anything
below PAGE_SIZE-1 is treated as PAGE_SIZE-1.
.max_write_len for "release_agent" is updated to PATH_MAX-1 and
cgroup_release_agent_write() is updated so that the redundant strlen()
check is removed and it uses strlcpy() instead of strcpy().
.max_write_len initializations in blk-throttle.c and cfq-iosched.c are
no longer necessary and removed. The one in cpuset is kept unchanged
as it's an approximated value to begin with.
This will also make transition to kernfs smoother.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index eb002c622cd6..fde3633ef389 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2213,13 +2213,14 @@ static int cgroup_procs_write(struct cgroup_subsys_state *css, | |||
2213 | static int cgroup_release_agent_write(struct cgroup_subsys_state *css, | 2213 | static int cgroup_release_agent_write(struct cgroup_subsys_state *css, |
2214 | struct cftype *cft, const char *buffer) | 2214 | struct cftype *cft, const char *buffer) |
2215 | { | 2215 | { |
2216 | BUILD_BUG_ON(sizeof(css->cgroup->root->release_agent_path) < PATH_MAX); | 2216 | struct cgroupfs_root *root = css->cgroup->root; |
2217 | if (strlen(buffer) >= PATH_MAX) | 2217 | |
2218 | return -EINVAL; | 2218 | BUILD_BUG_ON(sizeof(root->release_agent_path) < PATH_MAX); |
2219 | if (!cgroup_lock_live_group(css->cgroup)) | 2219 | if (!cgroup_lock_live_group(css->cgroup)) |
2220 | return -ENODEV; | 2220 | return -ENODEV; |
2221 | spin_lock(&release_agent_path_lock); | 2221 | spin_lock(&release_agent_path_lock); |
2222 | strcpy(css->cgroup->root->release_agent_path, buffer); | 2222 | strlcpy(root->release_agent_path, buffer, |
2223 | sizeof(root->release_agent_path)); | ||
2223 | spin_unlock(&release_agent_path_lock); | 2224 | spin_unlock(&release_agent_path_lock); |
2224 | mutex_unlock(&cgroup_mutex); | 2225 | mutex_unlock(&cgroup_mutex); |
2225 | return 0; | 2226 | return 0; |
@@ -2245,20 +2246,17 @@ static int cgroup_sane_behavior_show(struct seq_file *seq, void *v) | |||
2245 | return 0; | 2246 | return 0; |
2246 | } | 2247 | } |
2247 | 2248 | ||
2248 | /* A buffer size big enough for numbers or short strings */ | ||
2249 | #define CGROUP_LOCAL_BUFFER_SIZE 64 | ||
2250 | |||
2251 | static ssize_t cgroup_file_write(struct file *file, const char __user *userbuf, | 2249 | static ssize_t cgroup_file_write(struct file *file, const char __user *userbuf, |
2252 | size_t nbytes, loff_t *ppos) | 2250 | size_t nbytes, loff_t *ppos) |
2253 | { | 2251 | { |
2254 | struct cfent *cfe = __d_cfe(file->f_dentry); | 2252 | struct cfent *cfe = __d_cfe(file->f_dentry); |
2255 | struct cftype *cft = __d_cft(file->f_dentry); | 2253 | struct cftype *cft = __d_cft(file->f_dentry); |
2256 | struct cgroup_subsys_state *css = cfe->css; | 2254 | struct cgroup_subsys_state *css = cfe->css; |
2257 | size_t max_bytes = cft->max_write_len ?: CGROUP_LOCAL_BUFFER_SIZE - 1; | 2255 | size_t max_bytes = max(cft->max_write_len, PAGE_SIZE); |
2258 | char *buf; | 2256 | char *buf; |
2259 | int ret; | 2257 | int ret; |
2260 | 2258 | ||
2261 | if (nbytes >= max_bytes) | 2259 | if (nbytes > max_bytes) |
2262 | return -E2BIG; | 2260 | return -E2BIG; |
2263 | 2261 | ||
2264 | buf = kmalloc(nbytes + 1, GFP_KERNEL); | 2262 | buf = kmalloc(nbytes + 1, GFP_KERNEL); |
@@ -3919,7 +3917,7 @@ static struct cftype cgroup_base_files[] = { | |||
3919 | .flags = CFTYPE_INSANE | CFTYPE_ONLY_ON_ROOT, | 3917 | .flags = CFTYPE_INSANE | CFTYPE_ONLY_ON_ROOT, |
3920 | .seq_show = cgroup_release_agent_show, | 3918 | .seq_show = cgroup_release_agent_show, |
3921 | .write_string = cgroup_release_agent_write, | 3919 | .write_string = cgroup_release_agent_write, |
3922 | .max_write_len = PATH_MAX, | 3920 | .max_write_len = PATH_MAX - 1, |
3923 | }, | 3921 | }, |
3924 | { } /* terminate */ | 3922 | { } /* terminate */ |
3925 | }; | 3923 | }; |