mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
sysctl: Generate do_proc_douintvec with a type-generic macro
Generate the behavior in do_proc_douintvec{,_w,_r} functions with
do_proc_dotypevec(uint). The originals (do_proc_douintvec{,_w,_r})
where created in the same way as do_proc_dotypevec but for individual
values (no vectors). In this commit we use the existing macro
implementation to extend do_proc_douintvec to include vectors of values.
Signed-off-by: Joel Granados <joel.granados@kernel.org>
This commit is contained in:
+1
-113
@@ -651,119 +651,7 @@ out: \
|
||||
|
||||
do_proc_dotypevec(int)
|
||||
do_proc_dotypevec(ulong)
|
||||
|
||||
static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer,
|
||||
size_t *lenp, loff_t *ppos,
|
||||
int (*conv)(bool *negp, unsigned long *u_ptr,
|
||||
unsigned int *k_ptr, int dir,
|
||||
const struct ctl_table *table))
|
||||
{
|
||||
unsigned long lval;
|
||||
int err = 0;
|
||||
size_t left;
|
||||
bool neg;
|
||||
char *p = buffer;
|
||||
|
||||
left = *lenp;
|
||||
|
||||
if (proc_first_pos_non_zero_ignore(ppos, table))
|
||||
goto bail_early;
|
||||
|
||||
if (left > PAGE_SIZE - 1)
|
||||
left = PAGE_SIZE - 1;
|
||||
|
||||
proc_skip_spaces(&p, &left);
|
||||
if (!left) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
err = proc_get_long(&p, &left, &lval, &neg,
|
||||
proc_wspace_sep,
|
||||
sizeof(proc_wspace_sep), NULL);
|
||||
if (err || neg) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (conv(&neg, &lval, (unsigned int *) table->data, 1, table)) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!err && left)
|
||||
proc_skip_spaces(&p, &left);
|
||||
|
||||
out_free:
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
||||
bail_early:
|
||||
*ppos += *lenp;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer,
|
||||
size_t *lenp, loff_t *ppos,
|
||||
int (*conv)(bool *negp, unsigned long *u_ptr,
|
||||
unsigned int *k_ptr, int dir,
|
||||
const struct ctl_table *table))
|
||||
{
|
||||
unsigned long lval;
|
||||
int err = 0;
|
||||
size_t left;
|
||||
bool negp;
|
||||
|
||||
left = *lenp;
|
||||
|
||||
if (conv(&negp, &lval, (unsigned int *) table->data, 0, table)) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
proc_put_long(&buffer, &left, lval, false);
|
||||
if (!left)
|
||||
goto out;
|
||||
|
||||
proc_put_char(&buffer, &left, '\n');
|
||||
|
||||
out:
|
||||
*lenp -= left;
|
||||
*ppos += *lenp;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_proc_douintvec(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos,
|
||||
int (*conv)(bool *negp, ulong *u_ptr, uint *k_ptr,
|
||||
int dir, const struct ctl_table *table))
|
||||
{
|
||||
unsigned int vleft;
|
||||
|
||||
if (!table->data || !table->maxlen || !*lenp ||
|
||||
(*ppos && SYSCTL_KERN_TO_USER(dir))) {
|
||||
*lenp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
vleft = table->maxlen / sizeof(unsigned int);
|
||||
|
||||
/*
|
||||
* Arrays are not supported, keep this simple. *Do not* add
|
||||
* support for them.
|
||||
*/
|
||||
if (vleft != 1) {
|
||||
*lenp = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (SYSCTL_USER_TO_KERN(dir))
|
||||
return do_proc_douintvec_w(table, buffer, lenp, ppos, conv);
|
||||
return do_proc_douintvec_r(table, buffer, lenp, ppos, conv);
|
||||
}
|
||||
do_proc_dotypevec(uint)
|
||||
|
||||
/**
|
||||
* proc_douintvec_conv - read a vector of unsigned ints with a custom converter
|
||||
|
||||
Reference in New Issue
Block a user