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>
This commit is contained in:
parent
f149371e9e
commit
196851bed5
1 changed files with 18 additions and 25 deletions
|
@ -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[] = {
|
||||
|
|
Loading…
Reference in a new issue