diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 70d083c6fb6b..3a99cc2df860 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1363,6 +1363,39 @@ static ssize_t cgroup_write_X64(struct cgroup *cgrp, struct cftype *cft, | |||
1363 | return retval; | 1363 | return retval; |
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | static ssize_t cgroup_write_string(struct cgroup *cgrp, struct cftype *cft, | ||
1367 | struct file *file, | ||
1368 | const char __user *userbuf, | ||
1369 | size_t nbytes, loff_t *unused_ppos) | ||
1370 | { | ||
1371 | char local_buffer[64]; | ||
1372 | int retval = 0; | ||
1373 | size_t max_bytes = cft->max_write_len; | ||
1374 | char *buffer = local_buffer; | ||
1375 | |||
1376 | if (!max_bytes) | ||
1377 | max_bytes = sizeof(local_buffer) - 1; | ||
1378 | if (nbytes >= max_bytes) | ||
1379 | return -E2BIG; | ||
1380 | /* Allocate a dynamic buffer if we need one */ | ||
1381 | if (nbytes >= sizeof(local_buffer)) { | ||
1382 | buffer = kmalloc(nbytes + 1, GFP_KERNEL); | ||
1383 | if (buffer == NULL) | ||
1384 | return -ENOMEM; | ||
1385 | } | ||
1386 | if (nbytes && copy_from_user(buffer, userbuf, nbytes)) | ||
1387 | return -EFAULT; | ||
1388 | |||
1389 | buffer[nbytes] = 0; /* nul-terminate */ | ||
1390 | strstrip(buffer); | ||
1391 | retval = cft->write_string(cgrp, cft, buffer); | ||
1392 | if (!retval) | ||
1393 | retval = nbytes; | ||
1394 | if (buffer != local_buffer) | ||
1395 | kfree(buffer); | ||
1396 | return retval; | ||
1397 | } | ||
1398 | |||
1366 | static ssize_t cgroup_common_file_write(struct cgroup *cgrp, | 1399 | static ssize_t cgroup_common_file_write(struct cgroup *cgrp, |
1367 | struct cftype *cft, | 1400 | struct cftype *cft, |
1368 | struct file *file, | 1401 | struct file *file, |
@@ -1440,6 +1473,8 @@ static ssize_t cgroup_file_write(struct file *file, const char __user *buf, | |||
1440 | return cft->write(cgrp, cft, file, buf, nbytes, ppos); | 1473 | return cft->write(cgrp, cft, file, buf, nbytes, ppos); |
1441 | if (cft->write_u64 || cft->write_s64) | 1474 | if (cft->write_u64 || cft->write_s64) |
1442 | return cgroup_write_X64(cgrp, cft, file, buf, nbytes, ppos); | 1475 | return cgroup_write_X64(cgrp, cft, file, buf, nbytes, ppos); |
1476 | if (cft->write_string) | ||
1477 | return cgroup_write_string(cgrp, cft, file, buf, nbytes, ppos); | ||
1443 | if (cft->trigger) { | 1478 | if (cft->trigger) { |
1444 | int ret = cft->trigger(cgrp, (unsigned int)cft->private); | 1479 | int ret = cft->trigger(cgrp, (unsigned int)cft->private); |
1445 | return ret ? ret : nbytes; | 1480 | return ret ? ret : nbytes; |