Commit 95d49778 authored by Joel Granados's avatar Joel Granados Committed by Luis Chamberlain
Browse files

sysctl: Add size to register_net_sysctl function



This commit adds size to the register_net_sysctl indirection function to
facilitate the removal of the sentinel elements (last empty markers)
from the ctl_table arrays. Though we don't actually remove any sentinels
in this commit, register_net_sysctl* now has the capability of
forwarding table_size for when that happens.

We create a new function register_net_sysctl_sz with an extra size
argument. A macro replaces the existing register_net_sysctl. The size in
the macro is SIZE_MAX instead of ARRAY_SIZE to avoid compilation errors
while we systematically migrate to register_net_sysctl_sz. Will change
to ARRAY_SIZE in subsequent commits.

Care is taken to add table_size to the stopping criteria in such a way
that when we remove the empty sentinel element, it will continue
stopping in the last element of the ctl_table array.

Signed-off-by: default avatarJoel Granados <j.granados@samsung.com>
Suggested-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
parent 3bc269cf
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -469,15 +469,17 @@ void unregister_pernet_device(struct pernet_operations *);

struct ctl_table;

#define register_net_sysctl(net, path, table)	\
	register_net_sysctl_sz(net, path, table, SIZE_MAX)
#ifdef CONFIG_SYSCTL
int net_sysctl_init(void);
struct ctl_table_header *register_net_sysctl(struct net *net, const char *path,
					     struct ctl_table *table);
struct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path,
					     struct ctl_table *table, size_t table_size);
void unregister_net_sysctl_table(struct ctl_table_header *header);
#else
static inline int net_sysctl_init(void) { return 0; }
static inline struct ctl_table_header *register_net_sysctl(struct net *net,
	const char *path, struct ctl_table *table)
static inline struct ctl_table_header *register_net_sysctl_sz(struct net *net,
	const char *path, struct ctl_table *table, size_t table_size)
{
	return NULL;
}
+13 −9
Original line number Diff line number Diff line
@@ -122,12 +122,13 @@ __init int net_sysctl_init(void)
 *    allocated.
 */
static void ensure_safe_net_sysctl(struct net *net, const char *path,
				   struct ctl_table *table)
				   struct ctl_table *table, size_t table_size)
{
	struct ctl_table *ent;

	pr_debug("Registering net sysctl (net %p): %s\n", net, path);
	for (ent = table; ent->procname; ent++) {
	ent = table;
	for (size_t i = 0; i < table_size && ent->procname; ent++, i++) {
		unsigned long addr;
		const char *where;

@@ -160,21 +161,24 @@ static void ensure_safe_net_sysctl(struct net *net, const char *path,
	}
}

struct ctl_table_header *register_net_sysctl(struct net *net,
	const char *path, struct ctl_table *table)
struct ctl_table_header *register_net_sysctl_sz(struct net *net,
						const char *path,
						struct ctl_table *table,
						size_t table_size)
{
	int count = 0;
	int count;
	struct ctl_table *entry;

	if (!net_eq(net, &init_net))
		ensure_safe_net_sysctl(net, path, table);
		ensure_safe_net_sysctl(net, path, table, table_size);

	for (entry = table; entry->procname; entry++)
		count++;
	entry = table;
	for (count = 0 ; count < table_size && entry->procname; entry++, count++)
		;

	return __register_sysctl_table(&net->sysctls, path, table, count);
}
EXPORT_SYMBOL_GPL(register_net_sysctl);
EXPORT_SYMBOL_GPL(register_net_sysctl_sz);

void unregister_net_sysctl_table(struct ctl_table_header *header)
{