diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-28 18:39:10 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-28 18:39:10 +0100 |
| commit | c9766f01268f4020946f22dfc79daff43b5cfeae (patch) | |
| tree | 8b019312e58dd254d9fe377f8c7b3f32fbc6ece7 /include | |
| parent | 39aed2e6099d2a77e69ce67e30c21dddb17fa1c8 (diff) | |
| parent | 894514dc2a35b57772a740b62b7542e6f41371ac (diff) | |
| download | linux-next-c9766f01268f4020946f22dfc79daff43b5cfeae.tar.gz linux-next-c9766f01268f4020946f22dfc79daff43b5cfeae.zip | |
Merge branch 'sysctl-next' of https://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl.git
# Conflicts:
# kernel/time/jiffies.c
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/sysctl.h | 131 |
1 files changed, 93 insertions, 38 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 2886fbceb5d6..e5d7226ab6f5 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -59,7 +59,7 @@ extern const int sysctl_vals[]; #define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1]) #define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2]) -/** +/* * * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1) * in the file_operations struct at proc/proc_sysctl.c. Its value means @@ -74,53 +74,108 @@ extern const int sysctl_vals[]; extern const unsigned long sysctl_long_vals[]; -typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer, - size_t *lenp, loff_t *ppos); - -int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_dobool(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); +typedef int proc_handler(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); -int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, +/* proc_handler functions */ +int proc_dostring(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dobool(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dointvec(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dointvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_douintvec(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_douintvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_dou8vec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_doulongvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_do_large_bitmap(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, loff_t *ppos); -int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, +int proc_do_static_key(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); + +/* + * proc_handler aggregators + * + * Create a proc_handler with a custom converter. Use when the user space + * value is a transformation of the kernel value. Cannot be passed as + * proc_handlers. + * + * Example of creating your custom proc handler: + * int custom_converter(bool *negp, ulong *u_ptr, uint *k_ptr, + * int dir, const struct ctl_table *ctl) {...} + * int custom_proc_handler(const struct ctl_table *ctl, int dir, + * void *buf, size_t *lenp, loff_t *ppos + * { return proc_dointvec_conv(ctl, dir, buf, lenp, ppos, custom_converter); } + */ +int proc_dointvec_conv(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, - int dir, const struct ctl_table *table)); -int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, - ulong (*k_ptr_op)(const ulong)); -int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, - ulong (*u_ptr_op)(const ulong)); + int dir, const struct ctl_table *ctl)); +int proc_douintvec_conv(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, ulong *u_ptr, uint *k_ptr, + int dir, const struct ctl_table *ctl)); +int proc_doulongvec_conv(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, ulong *u_ptr, ulong *k_ptr, + int dir, const struct ctl_table *ctl)); + +/* + * bi-directional converter functions + * + * Specify the converter function for both directions (user to kernel & kernel + * to user). Use when you want to change the value of the variable before + * assignment. Used to create custom proc_handler aggregators. + * + * Example of creating your custom bi-directional converter: + * int custom_u2k(ulong *u_ptr, const uint *k_ptr) { ... } + * int custom_converter(bool *negp, ulong *u_ptr, uint *k_ptr, + * int dir, const struct ctl_table *ctl) + * { return proc_uint_conv(u_ptr, k_ptr, dir, ctl, true, + * custom_u2k, proc_uint_k2u_conv} + */ int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, const struct ctl_table *tbl, bool k_ptr_range_check, int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)); - -int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); -int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, unsigned int *valp, - int write, const struct ctl_table *table)); -int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr); -int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, - ulong (*u_ptr_op)(const ulong)); int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, const struct ctl_table *tbl, bool k_ptr_range_check, int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr), int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr)); +int proc_ulong_conv(ulong *u_ptr, ulong *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const ulong *u_ptr, ulong *k_ptr), + int (*kern_to_user)(ulong *u_ptr, const ulong *k_ptr)); -int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); -int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, - void *buffer, size_t *lenp, loff_t *ppos, - unsigned long convmul, unsigned long convdiv); -int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_do_static_key(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); +/* + * uni-directional converter functions + * + * Specify the converter function for one directions (user to kernel or + * kernel to user). Use to call the actual value conversion. Used to Create + * bi-directional converters. + * + * Example of creating a uni-directional converter: + * ulong op(const ulong val) { ... } + * int custom_unidir_conv(ulong *u_ptr, const uint *k_ptr) + * { return proc_uint_k2u_conv_kop(u_ptr, k_ptr, op); } + */ +int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, + ulong (*k_ptr_op)(const ulong)); +int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, + ulong (*u_ptr_op)(const ulong)); +int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr); +int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, + ulong (*u_ptr_op)(const ulong)); +int proc_ulong_u2k_conv_uop(const ulong *u_ptr, ulong *k_ptr, + ulong (*u_ptr_op)(const ulong)); +int proc_ulong_k2u_conv_kop(ulong *u_ptr, const ulong *k_ptr, + ulong (*k_ptr_op)(const ulong)); /* * Register a set of sysctl names by calling register_sysctl @@ -190,9 +245,9 @@ struct ctl_node { * @nreg: When nreg drops to 0 the ctl_table_header will be unregistered. * @rcu: Delays the freeing of the inode. Introduced with "unfuck proc_sysctl ->d_compare()" * - * @type: Enumeration to differentiate between ctl target types - * @type.SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations - * @type.SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Identifies a permanently empty dir + * @type: Enumeration to differentiate between ctl target types: + * type.SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations + * type.SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Identifies a permanently empty dir * target to serve as a mount point */ struct ctl_table_header { |
