[PATCH] cgroup: Zero sized write should be no-op

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Do not report failure on zero sized writes, and handle them as no-op.

There's issues for example in case of writev() when there's iovec
containing zero buffer as a first one. It's expected writev() on below
example to successfully perform the write to specified writable cgroup
file expecting integer value, and to return 2. For now it's returning
value -1, and skipping the write:

	int writetest(int fd) {
	  const char *buf1 = "";
	  const char *buf2 = "1\n";
          struct iovec iov[2] = {
                { .iov_base = (void*)buf1, .iov_len = 0 },
                { .iov_base = (void*)buf2, .iov_len = 2 }
          };
	  return writev(fd, iov, 2);
	}

This patch fixes the issue by checking if there's nothing to write,
and handling the write as no-op by just returning 0.

Signed-off-by: Jouni Roivas <jouni.roivas@xxxxxxxxxx>
---
 kernel/cgroup/cgroup.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index dd247747ec14..331b050fd5f1 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -3222,6 +3222,9 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
 	char *tok;
 	int ssid, ret;
 
+	if (!nbytes)
+		return 0;
+
 	/*
 	 * Parse input - space separated list of subsystem names prefixed
 	 * with either + or -.
@@ -3385,6 +3388,9 @@ static ssize_t cgroup_type_write(struct kernfs_open_file *of, char *buf,
 	struct cgroup *cgrp;
 	int ret;
 
+	if (!nbytes)
+		return 0;
+
 	/* only switching to threaded mode is supported */
 	if (strcmp(strstrip(buf), "threaded"))
 		return -EINVAL;
@@ -3421,6 +3427,9 @@ static ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of,
 	int descendants;
 	ssize_t ret;
 
+	if (!nbytes)
+		return 0;
+
 	buf = strstrip(buf);
 	if (!strcmp(buf, "max")) {
 		descendants = INT_MAX;
@@ -3464,6 +3473,9 @@ static ssize_t cgroup_max_depth_write(struct kernfs_open_file *of,
 	ssize_t ret;
 	int depth;
 
+	if (!nbytes)
+		return 0;
+
 	buf = strstrip(buf);
 	if (!strcmp(buf, "max")) {
 		depth = INT_MAX;
@@ -3569,6 +3581,9 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
 	struct psi_trigger *new;
 	struct cgroup *cgrp;
 
+	if (!nbytes)
+		return 0;
+
 	cgrp = cgroup_kn_lock_live(of->kn, false);
 	if (!cgrp)
 		return -ENODEV;
@@ -3638,6 +3653,9 @@ static ssize_t cgroup_freeze_write(struct kernfs_open_file *of,
 	ssize_t ret;
 	int freeze;
 
+	if (!nbytes)
+		return 0;
+
 	ret = kstrtoint(strstrip(buf), 0, &freeze);
 	if (ret)
 		return ret;
@@ -3682,6 +3700,9 @@ static ssize_t cgroup_file_write(struct kernfs_open_file *of, char *buf,
 	struct cgroup_subsys_state *css;
 	int ret;
 
+	if (!nbytes)
+		return 0;
+
 	/*
 	 * If namespaces are delegation boundaries, disallow writes to
 	 * files in an non-init namespace root from inside the namespace
@@ -4777,6 +4798,9 @@ static ssize_t cgroup_threads_write(struct kernfs_open_file *of,
 	ssize_t ret;
 	bool locked;
 
+	if (!nbytes)
+		return 0;
+
 	buf = strstrip(buf);
 
 	dst_cgrp = cgroup_kn_lock_live(of->kn, false);
-- 
2.25.1




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux