core_initcall(sysctl_init);
 
 /**
- * register_sysctl_table - register a sysctl hierarchy
+ * register_sysctl_paths - register a sysctl hierarchy
+ * @path: The path to the directory the sysctl table is in.
  * @table: the top-level table structure
  *
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. An entry with a ctl_name of 0 terminates the table. 
+ * array. A completely 0 filled entry terminates the table.
  *
  * The members of the &struct ctl_table structure are used as follows:
  *
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                                               struct ctl_table *table)
 {
-       struct ctl_table_header *tmp;
-       tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
-       if (!tmp)
+       struct ctl_table_header *header;
+       struct ctl_table *new, **prevp;
+       unsigned int n, npath;
+
+       /* Count the path components */
+       for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
+               ;
+
+       /*
+        * For each path component, allocate a 2-element ctl_table array.
+        * The first array element will be filled with the sysctl entry
+        * for this, the second will be the sentinel (ctl_name == 0).
+        *
+        * We allocate everything in one go so that we don't have to
+        * worry about freeing additional memory in unregister_sysctl_table.
+        */
+       header = kzalloc(sizeof(struct ctl_table_header) +
+                        (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
+       if (!header)
                return NULL;
-       tmp->ctl_table = table;
-       INIT_LIST_HEAD(&tmp->ctl_entry);
-       tmp->used = 0;
-       tmp->unregistering = NULL;
-       sysctl_set_parent(NULL, table);
-       if (sysctl_check_table(tmp->ctl_table)) {
-               kfree(tmp);
+
+       new = (struct ctl_table *) (header + 1);
+
+       /* Now connect the dots */
+       prevp = &header->ctl_table;
+       for (n = 0; n < npath; ++n, ++path) {
+               /* Copy the procname */
+               new->procname = path->procname;
+               new->ctl_name = path->ctl_name;
+               new->mode     = 0555;
+
+               *prevp = new;
+               prevp = &new->child;
+
+               new += 2;
+       }
+       *prevp = table;
+
+       INIT_LIST_HEAD(&header->ctl_entry);
+       header->used = 0;
+       header->unregistering = NULL;
+       sysctl_set_parent(NULL, header->ctl_table);
+       if (sysctl_check_table(header->ctl_table)) {
+               kfree(header);
                return NULL;
        }
        spin_lock(&sysctl_lock);
-       list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
+       list_add_tail(&header->ctl_entry, &root_table_header.ctl_entry);
        spin_unlock(&sysctl_lock);
-       return tmp;
+
+       return header;
+}
+
+/**
+ * register_sysctl_table - register a sysctl table hierarchy
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
+{
+       static const struct ctl_path null_path[] = { {} };
+
+       return register_sysctl_paths(null_path, table);
 }
 
 /**
        return NULL;
 }
 
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                                                   struct ctl_table *table)
+{
+       return NULL;
+}
+
 void unregister_sysctl_table(struct ctl_table_header * table)
 {
 }
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_table);
+EXPORT_SYMBOL(register_sysctl_paths);
 EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);