diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 89150494bd10..1371d7b86810 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -1022,6 +1022,7 @@ struct ctl_table int maxlen; mode_t mode; ctl_table *child; + ctl_table *parent; /* Automatically set */ proc_handler *proc_handler; /* Callback for text formatting */ ctl_handler *strategy; /* Callback function for all r/w */ struct proc_dir_entry *de; /* /proc control block */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b3ee791ad663..3ca1d5ff0319 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1240,6 +1240,23 @@ int do_sysctl_strategy (ctl_table *table, } #endif /* CONFIG_SYSCTL_SYSCALL */ +static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) +{ + for (; table->ctl_name || table->procname; table++) { + table->parent = parent; + if (table->child) + sysctl_set_parent(table, table->child); + } +} + +static __init int sysctl_init(void) +{ + sysctl_set_parent(NULL, root_table); + return 0; +} + +core_initcall(sysctl_init); + /** * register_sysctl_table - register a sysctl hierarchy * @table: the top-level table structure @@ -1318,6 +1335,7 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table) INIT_LIST_HEAD(&tmp->ctl_entry); tmp->used = 0; tmp->unregistering = NULL; + sysctl_set_parent(NULL, table); spin_lock(&sysctl_lock); list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); spin_unlock(&sysctl_lock);