소스 검색

s390/topology: correct topology mode proc handler

Reuse proc_douintvec_minmax to simplify topology mode proc handler.
This also enforces correct range of 0-1 on proc writes and correctly
handles numbers starting with 0 or spaces.

Before:
$ echo 01 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
0
$ echo ' 1' > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 2 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 12 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1

After:
$ echo 01 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1
$ echo ' 1' > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1
$ echo 2 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 12 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo '   0' > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
0

Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Vasily Gorbik 7 년 전
부모
커밋
196851bed5
1개의 변경된 파일18개의 추가작업 그리고 25개의 파일을 삭제
  1. 18 25
      arch/s390/kernel/topology.c

+ 18 - 25
arch/s390/kernel/topology.c

@@ -579,40 +579,33 @@ early_param("topology", topology_setup);
 static int topology_ctl_handler(struct ctl_table *ctl, int write,
 				void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	unsigned int len;
+	int enabled = topology_is_enabled();
 	int new_mode;
-	char buf[2];
+	int zero = 0;
+	int one = 1;
+	int rc;
+	struct ctl_table ctl_entry = {
+		.procname	= ctl->procname,
+		.data		= &enabled,
+		.maxlen		= sizeof(int),
+		.extra1		= &zero,
+		.extra2		= &one,
+	};
+
+	rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos);
+	if (rc < 0 || !write)
+		return rc;
 
-	if (!*lenp || *ppos) {
-		*lenp = 0;
-		return 0;
-	}
-	if (!write) {
-		memcpy(buf, topology_is_enabled() ? "1\n" : "0\n", ARRAY_SIZE(buf));
-		len = strnlen(buf, ARRAY_SIZE(buf));
-		if (len > *lenp)
-			len = *lenp;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-		goto out;
-	}
-	len = *lenp;
-	if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len))
-		return -EFAULT;
-	if (buf[0] != '0' && buf[0] != '1')
-		return -EINVAL;
 	mutex_lock(&smp_cpu_state_mutex);
-	new_mode = topology_get_mode(buf[0] == '1');
+	new_mode = topology_get_mode(enabled);
 	if (topology_mode != new_mode) {
 		topology_mode = new_mode;
 		topology_schedule_update();
 	}
 	mutex_unlock(&smp_cpu_state_mutex);
 	topology_flush_work();
-out:
-	*lenp = len;
-	*ppos += len;
-	return 0;
+
+	return rc;
 }
 
 static struct ctl_table topology_ctl_table[] = {