sysctl: Add size to register_sysctl

This commit adds table_size to register_sysctl in preparation for the
removal of the sentinel elements in the ctl_table arrays (last empty
markers). And though we do *not* remove any sentinels in this commit, we
set things up by either passing the table_size explicitly or using
ARRAY_SIZE on the ctl_table arrays.

We replace the register_syctl function with a macro that will add the
ARRAY_SIZE to the new register_sysctl_sz function. In this way the
callers that are already using an array of ctl_table structs do not
change. For the callers that pass a ctl_table array pointer, we pass the
table_size to register_sysctl_sz instead of the macro.

Signed-off-by: Joel Granados <j.granados@samsung.com>
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
This commit is contained in:
Joel Granados 2023-08-09 12:49:58 +02:00 committed by Luis Chamberlain
parent bff97cf11b
commit 9edbfe92a0
6 changed files with 28 additions and 20 deletions

View file

@ -569,7 +569,7 @@ static void __init register_insn_emulation(struct insn_emulation *insn)
sysctl->extra2 = &insn->max;
sysctl->proc_handler = emulation_proc_handler;
register_sysctl("abi", sysctl);
register_sysctl_sz("abi", sysctl, 1);
}
}

View file

@ -365,7 +365,7 @@ int appldata_register_ops(struct appldata_ops *ops)
ops->ctl_table[0].proc_handler = appldata_generic_handler;
ops->ctl_table[0].data = ops;
ops->sysctl_header = register_sysctl(appldata_proc_name, ops->ctl_table);
ops->sysctl_header = register_sysctl_sz(appldata_proc_name, ops->ctl_table, 1);
if (!ops->sysctl_header)
goto out;
return 0;

View file

@ -43,7 +43,7 @@ static struct ctl_table sysctl_mount_point[] = {
*/
struct ctl_table_header *register_sysctl_mount_point(const char *path)
{
return register_sysctl(path, sysctl_mount_point);
return register_sysctl_sz(path, sysctl_mount_point, 0);
}
EXPORT_SYMBOL(register_sysctl_mount_point);
@ -1399,7 +1399,7 @@ struct ctl_table_header *__register_sysctl_table(
}
/**
* register_sysctl - register a sysctl table
* register_sysctl_sz - register a sysctl table
* @path: The path to the directory the sysctl table is in. If the path
* doesn't exist we will create it for you.
* @table: the table structure. The calller must ensure the life of the @table
@ -1409,25 +1409,20 @@ struct ctl_table_header *__register_sysctl_table(
* to call unregister_sysctl_table() and can instead use something like
* register_sysctl_init() which does not care for the result of the syctl
* registration.
* @table_size: The number of elements in table.
*
* Register a sysctl table. @table should be a filled in ctl_table
* array. A completely 0 filled entry terminates the table.
*
* See __register_sysctl_table for more details.
*/
struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
struct ctl_table_header *register_sysctl_sz(const char *path, struct ctl_table *table,
size_t table_size)
{
int count = 0;
struct ctl_table *entry;
struct ctl_table_header t_hdr;
t_hdr.ctl_table = table;
list_for_each_table_entry(entry, (&t_hdr))
count++;
return __register_sysctl_table(&sysctl_table_root.default_set,
path, table, count);
path, table, table_size);
}
EXPORT_SYMBOL(register_sysctl);
EXPORT_SYMBOL(register_sysctl_sz);
/**
* __register_sysctl_init() - register sysctl table to path
@ -1452,10 +1447,17 @@ EXPORT_SYMBOL(register_sysctl);
void __init __register_sysctl_init(const char *path, struct ctl_table *table,
const char *table_name)
{
struct ctl_table_header *hdr = register_sysctl(path, table);
int count = 0;
struct ctl_table *entry;
struct ctl_table_header t_hdr, *hdr;
t_hdr.ctl_table = table;
list_for_each_table_entry(entry, (&t_hdr))
count++;
hdr = register_sysctl_sz(path, table, count);
if (unlikely(!hdr)) {
pr_err("failed when register_sysctl %s to %s\n", table_name, path);
pr_err("failed when register_sysctl_sz %s to %s\n", table_name, path);
return;
}
kmemleak_not_leak(hdr);

View file

@ -215,6 +215,9 @@ struct ctl_path {
const char *procname;
};
#define register_sysctl(path, table) \
register_sysctl_sz(path, table, ARRAY_SIZE(table))
#ifdef CONFIG_SYSCTL
void proc_sys_poll_notify(struct ctl_table_poll *poll);
@ -227,7 +230,8 @@ extern void retire_sysctl_set(struct ctl_table_set *set);
struct ctl_table_header *__register_sysctl_table(
struct ctl_table_set *set,
const char *path, struct ctl_table *table, size_t table_size);
struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table);
struct ctl_table_header *register_sysctl_sz(const char *path, struct ctl_table *table,
size_t table_size);
void unregister_sysctl_table(struct ctl_table_header * table);
extern int sysctl_init_bases(void);
@ -262,7 +266,9 @@ static inline struct ctl_table_header *register_sysctl_mount_point(const char *p
return NULL;
}
static inline struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
static inline struct ctl_table_header *register_sysctl_sz(const char *path,
struct ctl_table *table,
size_t table_size)
{
return NULL;
}

View file

@ -365,7 +365,7 @@ static __init int user_namespace_sysctl_init(void)
* default set so that registrations in the child sets work
* properly.
*/
user_header = register_sysctl("user", empty);
user_header = register_sysctl_sz("user", empty, 0);
kmemleak_ignore(user_header);
BUG_ON(!user_header);
BUG_ON(!setup_userns_sysctls(&init_user_ns));

View file

@ -101,7 +101,7 @@ __init int net_sysctl_init(void)
* registering "/proc/sys/net" as an empty directory not in a
* network namespace.
*/
net_header = register_sysctl("net", empty);
net_header = register_sysctl_sz("net", empty, 0);
if (!net_header)
goto out;
ret = register_pernet_subsys(&sysctl_pernet_ops);