Netdev List
 help / color / mirror / Atom feed
* [v2 077/115] sysctl: add duplicate entry and sanity ctl_table checks
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 include/linux/sysctl.h |    7 ++
 kernel/sysctl.c        |   19 ++++++-
 kernel/sysctl_check.c  |  153 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index b626271..22b6eb8 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1092,6 +1092,13 @@ extern struct ctl_table_header *register_sysctl_paths(const struct ctl_path *pat
 						      struct ctl_table *table);
 extern void unregister_sysctl_table(struct ctl_table_header *table);
 
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+extern int sysctl_check_table(const struct ctl_path *path,
+			      int nr_dirs,
+			      struct ctl_table *table);
+extern int sysctl_check_duplicates(struct ctl_table_header *header);
+#endif /* CONFIG_SYSCTL_SYSCALL_CHECK */
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SYSCTL_H */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index cbf33b1..d777e89 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1977,8 +1977,14 @@ struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *group,
 	const struct ctl_path *path, struct ctl_table *table)
 {
 	struct ctl_table_header *header;
+	int failed_duplicate_check = 0;
 	int nr_dirs = ctl_path_items(path);
 
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+	if (sysctl_check_table(path, nr_dirs, table))
+		return NULL;
+#endif
+
 	header = alloc_sysctl_header(group);
 	if (!header)
 		return NULL;
@@ -1993,9 +1999,20 @@ struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *group,
 	header->ctl_header_refs = 1;
 
 	sysctl_write_lock_head(header->parent);
-	list_add_tail(&header->ctl_entry, &header->parent->ctl_tables);
+
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+	failed_duplicate_check = sysctl_check_duplicates(header);
+#endif
+	if (!failed_duplicate_check)
+		list_add_tail(&header->ctl_entry, &header->parent->ctl_tables);
+
 	sysctl_write_unlock_head(header->parent);
 
+	if (failed_duplicate_check) {
+		unregister_sysctl_table(header);
+		return NULL;
+	}
+
 	return header;
 }
 
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index e9a7a58..4e0bce5 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -1 +1,152 @@
-/* will be rewritten */
+#include <linux/sysctl.h>
+#include <linux/string.h>
+
+/*
+ * @path: the path to the offender
+ * @offender is the name of a file or directory that violated some sysctl rules.
+ * @str: a message accompanying the error
+ */
+static void fail(const struct ctl_path *path,
+		 const char *offender,
+		 const char *str)
+{
+	printk(KERN_ERR "sysctl sanity check failed: ");
+
+	for (; path->procname; path++)
+		printk("/%s", path->procname);
+
+	if (offender)
+		printk("/%s", offender);
+
+	printk(": %s\n", str);
+}
+
+#define FAIL(str) do { fail(path, t->procname, str); error = -EINVAL;} while (0)
+
+int sysctl_check_table(const struct ctl_path *path,
+		       int nr_dirs,
+		       struct ctl_table *table)
+{
+	struct ctl_table *t;
+	int error = 0;
+
+	if (nr_dirs > CTL_MAXNAME - 1) {
+		fail(path, NULL, "tree too deep");
+		error = -EINVAL;
+	}
+
+	for(t = table; t->procname; t++) {
+		if ((t->proc_handler == proc_dostring) ||
+		    (t->proc_handler == proc_dointvec) ||
+		    (t->proc_handler == proc_dointvec_minmax) ||
+		    (t->proc_handler == proc_dointvec_jiffies) ||
+		    (t->proc_handler == proc_dointvec_userhz_jiffies) ||
+		    (t->proc_handler == proc_dointvec_ms_jiffies) ||
+		    (t->proc_handler == proc_doulongvec_minmax) ||
+		    (t->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+			if (!t->data)
+				FAIL("No data");
+			if (!t->maxlen)
+				FAIL("No maxlen");
+		}
+#ifdef CONFIG_PROC_SYSCTL
+		if (!t->proc_handler)
+			FAIL("No proc_handler");
+#endif
+		if (t->mode > 0777)
+			FAIL("bogus .mode");
+	}
+
+	if (error)
+		dump_stack();
+
+	return error;
+}
+
+
+/*
+ * @dir: the directory imediately above the offender
+ * @offender is the name of a file or directory that violated some sysctl rules.
+ */
+static void duplicate_error(struct ctl_table_header *dir,
+			    const char *offender)
+{
+	const char *names[CTL_MAXNAME];
+	int i = 0;
+
+	printk(KERN_ERR "sysctl duplicate check failed: ");
+
+	for (; dir->parent; dir = dir->parent)
+		/* ctl_dirname can be NULL: netns-correspondent
+		 * directories do not have a ctl_dirname. Their only
+		 * pourpose is to hold the list of
+		 * subdirs/subtables. They hold netns-specific
+		 * information for the parent directory. */
+		if (dir->ctl_dirname) {
+			names[i] = dir->ctl_dirname;
+			i++;
+		}
+
+	/* Print the names in the normal path order, not reversed */
+	for(i--; i >= 0; i--)
+		printk("/%s", names[i]);
+
+	printk("/%s \n", offender);
+}
+
+/* is there an entry in the table with the same procname? */
+static int match(struct ctl_table *table, const char *name)
+{
+	for ( ; table->procname; table++) {
+
+		if (strcmp(table->procname, name) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+
+/* Called under header->parent write lock.
+ *
+ * checks whether this header's table introduces items that have the
+ * same names as other items at the same level (other files or
+ * subdirectories of the current dir). */
+int sysctl_check_duplicates(struct ctl_table_header *header)
+{
+	int has_duplicates = 0;
+	struct ctl_table *table = header->ctl_table_arg;
+	struct ctl_table_header *dir = header->parent;
+	struct ctl_table_header *h;
+
+	list_for_each_entry(h, &dir->ctl_subdirs, ctl_entry) {
+		if (IS_ERR(sysctl_use_header(h)))
+			continue;
+
+		if (match(table, h->ctl_dirname)) {
+			has_duplicates = 1;
+			duplicate_error(dir, h->ctl_dirname);
+		}
+
+		sysctl_unuse_header(h);
+	}
+
+	list_for_each_entry(h, &dir->ctl_tables, ctl_entry) {
+		ctl_table *t;
+
+		if (IS_ERR(sysctl_use_header(h)))
+			continue;
+
+		for (t = h->ctl_table_arg; t->procname; t++) {
+			if (match(table, t->procname)) {
+				has_duplicates = 1;
+				duplicate_error(dir, t->procname);
+			}
+		}
+		sysctl_unuse_header(h);
+	}
+
+	if (has_duplicates)
+		dump_stack();
+
+	return has_duplicates;
+}
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 078/115] sysctl: alloc ctl_table_header with kmem_cache
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Because now ctl_table_header objects are allocated with a fixed size
buffer (sizeof(struct ctl_table_header)) we can do the allocations
with kmem_cache.

Also, by making sure that the objects that are returned to the cache
are in a sane state we don't waste time reinitializing every field
after kmem_cache_alloc. We only initialize fields that were not left
with a sane value before returning an object to the cache.

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 kernel/sysctl.c |   48 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index d777e89..c207c19 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -198,6 +198,9 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
 
 #endif
 
+/* cache for ctl_table_header objects */
+static struct kmem_cache *sysctl_header_cachep;
+
 /* uses default ops */
 static const struct ctl_table_group_ops root_table_group_ops = { };
 
@@ -1553,7 +1556,9 @@ void sysctl_proc_inode_get(struct ctl_table_header *head)
 
 static void free_head(struct rcu_head *rcu)
 {
-	kfree(container_of(rcu, struct ctl_table_header, rcu));
+	struct ctl_table_header *header;
+	header = container_of(rcu, struct ctl_table_header, rcu);
+	kmem_cache_free(sysctl_header_cachep, header);
 }
 
 void sysctl_proc_inode_put(struct ctl_table_header *head)
@@ -1664,6 +1669,8 @@ int sysctl_perm(struct ctl_table_group *group, struct ctl_table *table, int op)
 	return test_perm(mode, op);
 }
 
+static void sysctl_header_ctor(void *data);
+
 __init int sysctl_init(void)
 {
 	struct ctl_table_header *kern_header, *vm_header, *fs_header,
@@ -1672,6 +1679,12 @@ __init int sysctl_init(void)
 	struct ctl_table_header *binfmt_misc_header;
 #endif
 
+	sysctl_header_cachep = kmem_cache_create("sysctl_header_cachep",
+					       sizeof(struct ctl_table_header),
+					       0, 0, &sysctl_header_ctor);
+	if (!sysctl_header_cachep)
+		goto fail_alloc_cachep;
+
 	kern_header = register_sysctl_paths(kern_path, kern_table);
 	if (kern_header == NULL)
 		goto fail_register_kern;
@@ -1715,6 +1728,8 @@ fail_register_fs:
 fail_register_vm:
 	unregister_sysctl_table(kern_header);
 fail_register_kern:
+	kmem_cache_destroy(sysctl_header_cachep);
+fail_alloc_cachep:
 	return -ENOMEM;
 }
 
@@ -1735,19 +1750,34 @@ static int ctl_path_items(const struct ctl_path *path)
 	return n;
 }
 
+static void sysctl_header_ctor(void *data)
+{
+	struct ctl_table_header *h = data;
+
+	h->ctl_use_refs = 0;
+	h->ctl_procfs_refs = 0;
+	h->ctl_header_refs = 0;
+
+	INIT_LIST_HEAD(&h->ctl_entry);
+	INIT_LIST_HEAD(&h->ctl_subdirs);
+	INIT_LIST_HEAD(&h->ctl_tables);
+}
 
 static struct ctl_table_header *alloc_sysctl_header(struct ctl_table_group *group)
 {
 	struct ctl_table_header *h;
 
-	h = kzalloc(sizeof(*h), GFP_KERNEL);
+	h = kmem_cache_alloc(sysctl_header_cachep, GFP_KERNEL);
 	if (!h)
 		return NULL;
 
+	/* - all _refs members are zero before freeing
+	 * - all list_head members point to themselves (empty lists) */
+
+	h->ctl_table_arg = NULL;
+	h->unregistering = NULL;
 	h->ctl_group = group;
-	INIT_LIST_HEAD(&h->ctl_entry);
-	INIT_LIST_HEAD(&h->ctl_subdirs);
-	INIT_LIST_HEAD(&h->ctl_tables);
+
 	return h;
 }
 
@@ -1905,12 +1935,12 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,
 		parent = mkdir_netns_corresp(parent, group, &__netns_corresp);
 
 	if (__netns_corresp)
-		kfree(__netns_corresp);
+		kmem_cache_free(sysctl_header_cachep, __netns_corresp);
 
 	/* free unused pre-allocated entries */
 	for (i = 0; i < nr_dirs; i++)
 		if (dirs[i])
-			kfree(dirs[i]);
+			kmem_cache_free(sysctl_header_cachep, dirs[i]);
 
 	return parent;
 
@@ -1918,7 +1948,7 @@ err_alloc_coresp:
 	i = nr_dirs;
 err_alloc_dir:
 	for (i--; i >= 0; i--)
-		kfree(dirs[i]);
+		kmem_cache_free(sysctl_header_cachep, dirs[i]);
 	return NULL;
 
 }
@@ -1991,7 +2021,7 @@ struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *group,
 
 	header->parent = sysctl_mkdirs(&root_table_header, group, path, nr_dirs);
 	if (!header->parent) {
-		kfree(header);
+		kmem_cache_free(sysctl_header_cachep, header);
 		return NULL;
 	}
 
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 079/115] sysctl: single subheader path: optimisation for paths used only once
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

This is an optimisation for registering paths that you know will be
used to register a single table. Because such directories will be used
only once, sysctl will always create an entry for it when it sees it.

When sysctl registers a table, for each directory that may be used
while registering other tables we do a linear search to see if it's
already added, and, if not, add it ourselves.

For example: each netdevice will register a single table under
    	  /proc/sys/net/ipv4/conf/DEVNAME/.

The 'DEVNAME' component of the path is not used to register other
headers, and we can optimise adding that directory: we don't have to
check if it's already registered.

This will have a positive performance impact when registering many
such directories because we're doing a O(nr of sibling directories)
search. With @has_just_one_subheader=1 set we skip that search and add
the directory directly because we know no other sibling directory with
the same name was registered.

NOTE: in this example setting @has_just_one_subheader=1 for the 'conf'
ctl_path would be wrong because it's used when registering other
subheaders too (e.g. subheaders for other netdevices).

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 include/linux/sysctl.h |   31 +++++++++++++++++++++++++++++++
 kernel/sysctl.c        |   12 +++++++-----
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 22b6eb8..bdc8c97 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1083,6 +1083,37 @@ struct ctl_table_header {
 /* struct ctl_path describes where in the hierarchy a table is added */
 struct ctl_path {
 	const char *procname;
+
+
+	/* This is an optimisation for registering paths that you know
+	 * will be used to register a single table. Because such
+	 * directories will be used only once, sysctl will always
+	 * create an entry for it when it sees it.
+	 *
+	 * When sysctl registers a table, for each directory that may
+	 * be used while registering other tables we do a linear
+	 * search to see if it's already added, and, if not, add it
+	 * ourselves.
+	 *
+	 * For example: each netdevice will register a single table
+	 * under /proc/sys/net/ipv4/conf/DEVNAME/.
+	 *
+	 * The 'DEVNAME' component of the path is not used to register
+	 * other headers, and we can optimise adding that directory:
+	 * we don't have to check if it's already registered.
+	 *
+	 * This will have a positive performance impact when
+	 * registering many such directories because we're doing a
+	 * O(nr of sibling directories) search. With
+	 * @has_just_one_subheader=1 set we skip that search and add
+	 * the directory directly because we know no other sibling
+	 * directory with the same name was registered.
+	 *
+	 * NOTE: in this example setting @has_just_one_subheader=1 for
+	 * the 'conf' ctl_path would be wrong because it's used when
+	 * registering other subheaders too (e.g. subheaders for other
+	 * netdevices). */
+	int has_just_one_subheader;
 };
 
 extern struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *g,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c207c19..9b2c05a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1906,11 +1906,13 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,
 	retry:
 		sysctl_write_lock_head(parent);
 
-		h = mkdir_existing_dir(parent, dirs[i]->ctl_dirname);
-		if (h != NULL) {
-			sysctl_write_unlock_head(parent);
-			parent = h;
-			continue;
+		if (!path[i].has_just_one_subheader) {
+			h = mkdir_existing_dir(parent, dirs[i]->ctl_dirname);
+			if (h != NULL) {
+				sysctl_write_unlock_head(parent);
+				parent = h;
+				continue;
+			}
 		}
 
 		if (likely(!create_first_netns_corresp)) {
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 081/115] sysctl: single subheader path: net/{ipv4|ipv6}/neigh/DEV/
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 net/core/neighbour.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 799f06e..63677be 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2818,7 +2818,13 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
 		{ .procname = "net",	 },
 		{ .procname = "proto",	 },
 		{ .procname = "neigh",	 },
-		{ .procname = "default", },
+		{
+			/* will be set to device name (NEIGH_CTL_PATH_DEV) */
+			.procname = "default",
+			/* skip duplicate name check; we're registering
+			 * just one subheader for this directory */
+			.has_just_one_subheader = 1,
+		},
 		{ },
 	};
 
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 082/115] sysctl: single subheader path: net/ipv6/conf/DEVICE-NAME/
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 net/ipv6/addrconf.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a7bda07..3a9f958 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4486,7 +4486,13 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
 		{ .procname = "net", },
 		{ .procname = "ipv6", },
 		{ .procname = "conf", },
-		{ /* to be set */ },
+		{
+			/* to be set bellow (ADDRCONF_CTL_PATH_DEV) */
+			.procname = NULL,
+			/* skip duplicate name check; we're registering
+			 * just one subheader for this directory */
+			.has_just_one_subheader = 1,
+		},
 		{ },
 	};
 
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 085/115] sysctl: single subheader path: kernel/sched_domain/CPU/DOMAIN/
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 kernel/sched.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 6e39b7c..8320365 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6250,7 +6250,13 @@ static void register_sched_domain_sysctl(void)
 		{ .procname = "kernel" },
 		{ .procname = "sched_domain" },
 		{ /* 'cpu0' */ },
-		{ /* 'domain0' */ },
+		{
+			/* 'domain0' */
+			.procname = NULL,
+			/* skip duplicate name check; we're registering
+			 * just one subheader for this directory */
+			.has_just_one_subheader = 1,
+		},
 		{  },
 	};
 
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 087/115] sysctl: check netns-specific registration order respected
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 include/linux/sysctl.h |    2 +
 kernel/sysctl.c        |   15 ++++++++-
 kernel/sysctl_check.c  |   78 ++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index bdc8c97..036d1aa 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1128,6 +1128,8 @@ extern int sysctl_check_table(const struct ctl_path *path,
 			      int nr_dirs,
 			      struct ctl_table *table);
 extern int sysctl_check_duplicates(struct ctl_table_header *header);
+extern int sysctl_check_netns_correspondents(struct ctl_table_header *header,
+					     struct ctl_table_group *group);
 #endif /* CONFIG_SYSCTL_SYSCALL_CHECK */
 
 #endif /* __KERNEL__ */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9b2c05a..9e50334 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1920,6 +1920,12 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,
 			sysctl_write_unlock_head(parent);
 			parent = h;
 			dirs[i] = NULL; /* I'm used, don't free me */
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+			if (sysctl_check_netns_correspondents(parent, group)) {
+				unregister_sysctl_table(h);
+				goto err_check_netns_correspondents;
+			}
+#endif
 			continue;
 		}
 
@@ -1946,11 +1952,18 @@ static struct ctl_table_header *sysctl_mkdirs(struct ctl_table_header *parent,
 
 	return parent;
 
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+err_check_netns_correspondents:
+	if (__netns_corresp)
+		kmem_cache_free(sysctl_header_cachep, __netns_corresp);
+#endif
+
 err_alloc_coresp:
 	i = nr_dirs;
 err_alloc_dir:
 	for (i--; i >= 0; i--)
-		kmem_cache_free(sysctl_header_cachep, dirs[i]);
+		if (dirs[i])
+			kmem_cache_free(sysctl_header_cachep, dirs[i]);
 	return NULL;
 
 }
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index 4e0bce5..55e797a 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -63,19 +63,14 @@ int sysctl_check_table(const struct ctl_path *path,
 	return error;
 }
 
-
-/*
- * @dir: the directory imediately above the offender
- * @offender is the name of a file or directory that violated some sysctl rules.
- */
-static void duplicate_error(struct ctl_table_header *dir,
-			    const char *offender)
+/* Print the path from to a sysctl directory. The header must *not*
+ * point to a ctl_table_header that wraps a ctl_table array, it must
+ * be a directory. */
+static void printk_sysctl_dir(struct ctl_table_header *dir)
 {
 	const char *names[CTL_MAXNAME];
 	int i = 0;
 
-	printk(KERN_ERR "sysctl duplicate check failed: ");
-
 	for (; dir->parent; dir = dir->parent)
 		/* ctl_dirname can be NULL: netns-correspondent
 		 * directories do not have a ctl_dirname. Their only
@@ -90,7 +85,18 @@ static void duplicate_error(struct ctl_table_header *dir,
 	/* Print the names in the normal path order, not reversed */
 	for(i--; i >= 0; i--)
 		printk("/%s", names[i]);
+}
+
+/*
+ * @dir: the directory imediately above the offender
+ * @offender is the name of a file or directory that violated some sysctl rules.
+ */
+static void duplicate_error(struct ctl_table_header *dir,
+			    const char *offender)
+{
 
+	printk(KERN_ERR "sysctl duplicate check failed: ");
+	printk_sysctl_dir(dir);
 	printk("/%s \n", offender);
 }
 
@@ -150,3 +156,57 @@ int sysctl_check_duplicates(struct ctl_table_header *header)
 
 	return has_duplicates;
 }
+
+/* Check whether adding this header respects the rule that no
+ * non-netns-specific directory will be registered after one with the
+ * same name, but netns-specific was registered before (and still is registered)
+ *
+ * E.g. This sequence of registrations is not valid:
+ *     - non-netns-specific: /net/ipv4/
+ *     -     netns-specific: /net/ipv4/conf/lo
+ *     - non-netns-specific: /net/ipv4/conf/
+
+ * because after first adding 'conf' as a netns specific directory,
+ * we're adding one non-netns specific.
+ *
+ * NOTE: in this example, the directory that has a netns-correspondent is 'ipv4'
+ */
+int sysctl_check_netns_correspondents(struct ctl_table_header *header,
+				      struct ctl_table_group *group)
+{
+	struct ctl_table_header *netns_corresp, *h;
+	int found = 0;
+	/* we're only checking registration of non-netns paths added,
+	 * because only those paths can violate the above rule. */
+	if (group->has_netns_corresp)
+		return 0;
+
+	netns_corresp = sysctl_use_netns_corresp(header->parent);
+	if (!netns_corresp)
+		return 0;
+
+	/* see if the netns_correspondent has a subdir
+	 * with the same as this non-netns specific header */
+	sysctl_read_lock_head(netns_corresp);
+	list_for_each_entry(h, &netns_corresp->ctl_subdirs, ctl_entry) {
+		if (IS_ERR(sysctl_use_header(h)))
+			continue;
+		if (strcmp(header->ctl_dirname, h->ctl_dirname) == 0) {
+			sysctl_unuse_header(h);
+			found = 1;
+			break;
+		}
+		sysctl_unuse_header(h);
+	}
+	sysctl_read_unlock_head(netns_corresp);
+
+	if (!found)
+		return 0;
+
+	printk(KERN_ERR "illegal sysctl registration of non-netns-specific "
+	       "directory after a netns-specific with the same name\n");
+	printk_sysctl_dir(header);
+	dump_stack();
+
+	return 1;
+}
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 091/115] sysctl: add register_sysctl_dir: register an empty sysctl directory
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 include/linux/sysctl.h |    5 +++--
 kernel/sysctl.c        |   37 +++++++++++++++++++++++++++++++++++++
 kernel/sysctl_check.c  |   15 +++++++++++----
 3 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 322246d..03842cc 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1133,11 +1133,12 @@ extern struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *
 							struct ctl_table *table);
 extern struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
 						      struct ctl_table *table);
+struct ctl_table_header *register_sysctl_dir(const struct ctl_path *path);
 extern void unregister_sysctl_table(struct ctl_table_header *table);
 
 #ifdef CONFIG_SYSCTL_SYSCALL_CHECK
-extern int sysctl_check_table(const struct ctl_path *path,
-			      int nr_dirs,
+extern int sysctl_check_path(const struct ctl_path *path, int nr_dirs);
+extern int sysctl_check_table(const struct ctl_path *path, int nr_dirs,
 			      struct ctl_table *table);
 extern int sysctl_check_duplicates(struct ctl_table_header *header);
 extern int sysctl_check_netns_correspondents(struct ctl_table_header *header,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 94fff4e..7cf0242 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2045,6 +2045,9 @@ struct ctl_table_header *__register_sysctl_paths(struct ctl_table_group *group,
 	int dirs_created = 0;
 
 #ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+	if (sysctl_check_path(path, nr_dirs))
+		return NULL;
+
 	if (sysctl_check_table(path, nr_dirs, table))
 		return NULL;
 #endif
@@ -2098,6 +2101,39 @@ struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
 	return __register_sysctl_paths(&root_table_group, path, table);
 }
 
+/* Register an empty sysctl directory. */
+static struct ctl_table_header *__register_sysctl_dir(
+	struct ctl_table_group *group, const struct ctl_path *path)
+{
+	struct ctl_table_header *dir;
+	int nr_dirs = ctl_path_items(path);
+	int dirs_created = 0;
+
+#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
+	if (sysctl_check_path(path, nr_dirs))
+		return NULL;
+#endif
+
+	dir = sysctl_mkdirs(&root_table_header, group, path,
+			    nr_dirs, &dirs_created);
+	if (!dir)
+		return NULL;
+
+	/* -1 because we don't want to count ourselves in the list of
+         * directory headers owned by @dir. NOTE: if all of the dirs
+         * in the path are already registered dirs_created will be 0. */
+	if (dirs_created > 0)
+		dir->ctl_owned_dirs_refs = dirs_created - 1;
+	else
+		dir->ctl_owned_dirs_refs = 0;
+	return dir;
+}
+
+struct ctl_table_header *register_sysctl_dir(const struct ctl_path *path)
+{
+	return __register_sysctl_dir(&root_table_group, path);
+}
+
 /**
  * unregister_sysctl_table - unregister a sysctl table hierarchy
  * @header: the header returned from __register_sysctl_paths
@@ -3193,4 +3229,5 @@ EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_paths);
+EXPORT_SYMBOL(register_sysctl_dir);
 EXPORT_SYMBOL(unregister_sysctl_table);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index 205f721..20c1948 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -24,6 +24,17 @@ static void fail(const struct ctl_path *path,
 
 #define FAIL(str) do { fail(path, t->procname, str); error = -EINVAL;} while (0)
 
+
+int sysctl_check_path(const struct ctl_path *path,
+		      int nr_dirs)
+{
+	if (nr_dirs <= CTL_MAXNAME - 1)
+		return 0;
+	fail(path, NULL, "tree too deep");
+	return -EINVAL;
+}
+
+
 int sysctl_check_table(const struct ctl_path *path,
 		       int nr_dirs,
 		       struct ctl_table *table)
@@ -33,10 +44,6 @@ int sysctl_check_table(const struct ctl_path *path,
 	unsigned int nr_files = 0;
 	int error = 0;
 
-	if (nr_dirs > CTL_MAXNAME - 1) {
-		fail(path, NULL, "tree too deep");
-		error = -EINVAL;
-	}
 
 	for(t = table; t->procname; t++) {
 		nr_files ++;
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 092/115] sysctl: sched: create empty dir with register_sysctl_dir
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 kernel/sched.c |   19 ++++---------------
 1 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 8320365..5cda526 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6302,16 +6302,11 @@ static void register_sched_domain_sysctl(void)
 
 	i = 0;
 	for_each_possible_cpu(cpu) {
-		struct ctl_table *empty = kzalloc(sizeof(*empty), GFP_KERNEL);
-		if (empty == NULL)
-			goto unregister_sd_cpudir_headers;
 		sd_path[SD_PATH_CPU].procname = sd_cpu_names[cpu];
 		sd_path[SD_PATH_DOM].procname = NULL; /* end of array sentinel */
-		sd_cpudir_headers[i] = register_sysctl_paths(sd_path, empty);
-		if (sd_cpudir_headers[i] == NULL) {
-			kfree(empty);
+		sd_cpudir_headers[i] = register_sysctl_dir(sd_path);
+		if (sd_cpudir_headers[i] == NULL)
 			goto unregister_sd_cpudir_headers;
-		}
 		i++;
 	}
 
@@ -6347,11 +6342,8 @@ unregister_sd_domain_headers:
 	i = sd_cpudir_headers_num;
 unregister_sd_cpudir_headers:
 	i--;
-	for(; i >= 0; i--) {
-		struct ctl_table *table = sd_cpudir_headers[i]->ctl_table_arg;
+	for(; i >= 0; i--)
 		unregister_sysctl_table(sd_cpudir_headers[i]);
-		kfree(table);
-	}
 
 	kfree(sd_domain_headers);
 fail_alloc_sd_domain_headers:
@@ -6391,11 +6383,8 @@ static void unregister_sched_domain_sysctl(void)
 		kfree(table);
 	}
 
-	for(i = sd_cpudir_headers_num - 1; i >= 0; i--) {
-		struct ctl_table *table = sd_cpudir_headers[i]->ctl_table_arg;
+	for(i = sd_cpudir_headers_num - 1; i >= 0; i--)
 		unregister_sysctl_table(sd_cpudir_headers[i]);
-		kfree(table);
-	}
 
 	kfree(sd_domain_headers);
 	kfree(sd_cpudir_headers);
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* [v2 096/115] sysctl: net/ipv6/neigh: create empty dir with register_sysctl_dir
From: Lucian Adrian Grijincu @ 2011-05-08 22:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 net/ipv6/sysctl_net_ipv6.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 1d2d8c7..bb57ab4 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -15,8 +15,6 @@
 #include <net/addrconf.h>
 #include <net/inet_frag.h>
 
-static struct ctl_table empty[1];
-
 static ctl_table ipv6_bindv6only_template[] = {
 	{
 		.procname	= "bindv6only",
@@ -173,7 +171,7 @@ static struct ctl_table_header *ip6_base;
 
 int ipv6_static_sysctl_register(void)
 {
-	ip6_base = register_sysctl_paths(net_ipv6_neigh_path, empty);
+	ip6_base = register_sysctl_dir(net_ipv6_neigh_path);
 	if (ip6_base == NULL)
 		return -ENOMEM;
 	return 0;
-- 
1.7.5.134.g1c08b

^ permalink raw reply related

* Re: pull request: batman-adv 2011-05-08
From: David Miller @ 2011-05-08 22:40 UTC (permalink / raw)
  To: sven-KaDOiPu9UxWEi8DpZVb4nw
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1304868284-9364-1-git-send-email-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>

From: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
Date: Sun,  8 May 2011 17:24:36 +0200

> Hi,
> 
> I would like to propose following patches for net-next-2.6/2.6.40. They
> include minor cleanups of comments, a big rename patch s/hna/tt/, but
> also a remove some duplicated code. The spinlock which protected the
> list of possible interfaces for batman-adv was completely replaced by
> rtnl_lock because we want to be in sync with the rest of the network
> stack and the extra spinlock made everything more complex without giving
> any additional feature (and rtnl_lock was already used everywhere).
> Related to this patch is also a fix which should prevent a deadlock
> between the sysfs code and the event listener. Also the reference
> counting in find_router was fixed when an error was detected after the
> refcounter was already increased. The only feature is the support for
> multiple vlans in the bridge loop detection code.
> 
> I will submit a patch to remove the atomic_dec_not_zero from main.h
> after Linus accepted the patch you already saw.

Pulled, thanks Sven.

^ permalink raw reply

* [v2 001/115] sysctl: remove .child from dev/parport/default
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

First patch in a series that will end with a rewrite of sysctl. The
new implementation needs to get rid of the .child field of ctl_table.

Same functionality, but a little more clarity.

MAINTAINERS says parport is "Orphan" and I don't have a parallel
port. I minimally tested this patch, but I don't know who to resort to
for an ACK.

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 drivers/parport/procfs.c |   96 +++++++++++++++++++---------------------------
 1 files changed, 40 insertions(+), 56 deletions(-)

diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index 3f56bc0..89b8b71 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -419,56 +419,6 @@ parport_device_sysctl_template = {
 	}
 };
 
-struct parport_default_sysctl_table
-{
-	struct ctl_table_header *sysctl_header;
-	ctl_table vars[3];
-        ctl_table default_dir[2];
-	ctl_table parport_dir[2];
-	ctl_table dev_dir[2];
-};
-
-static struct parport_default_sysctl_table
-parport_default_sysctl_table = {
-	.sysctl_header	= NULL,
-	{
-		{
-			.procname	= "timeslice",
-			.data		= &parport_default_timeslice,
-			.maxlen		= sizeof(parport_default_timeslice),
-			.mode		= 0644,
-			.proc_handler	= proc_doulongvec_ms_jiffies_minmax,
-			.extra1		= (void*) &parport_min_timeslice_value,
-			.extra2		= (void*) &parport_max_timeslice_value
-		},
-		{
-			.procname	= "spintime",
-			.data		= &parport_default_spintime,
-			.maxlen		= sizeof(parport_default_spintime),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_minmax,
-			.extra1		= (void*) &parport_min_spintime_value,
-			.extra2		= (void*) &parport_max_spintime_value
-		},
-		{}
-	},
-	{
-		{
-			.procname	= "default",
-			.mode		= 0555,
-			.child		= parport_default_sysctl_table.vars
-		},
-		{}
-	},
-	{
-		PARPORT_PARPORT_DIR(parport_default_sysctl_table.default_dir),
-		{}
-	},
-	{
-		PARPORT_DEV_DIR(parport_default_sysctl_table.parport_dir),
-		{}
-	}
-};
 
 
 int parport_proc_register(struct parport *port)
@@ -558,19 +508,53 @@ int parport_device_proc_unregister(struct pardevice *device)
 	return 0;
 }
 
+
+static struct ctl_table_header *parport_default_sysctl_header;
+
+static struct ctl_table parport_default_sysctl_table[] = {
+	{
+		.procname	= "timeslice",
+		.data		= &parport_default_timeslice,
+		.maxlen		= sizeof(parport_default_timeslice),
+		.mode		= 0644,
+		.proc_handler	= proc_doulongvec_ms_jiffies_minmax,
+		.extra1		= (void*) &parport_min_timeslice_value,
+		.extra2		= (void*) &parport_max_timeslice_value
+	},
+	{
+		.procname	= "spintime",
+		.data		= &parport_default_spintime,
+		.maxlen		= sizeof(parport_default_spintime),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= (void*) &parport_min_spintime_value,
+		.extra2		= (void*) &parport_max_spintime_value
+	},
+	{ },
+};
+
+static const __initdata struct ctl_path parport_default_path[] = {
+	{ .procname = "dev" },
+	{ .procname = "parport" },
+	{ .procname = "default" },
+	{  },
+};
+
 static int __init parport_default_proc_register(void)
 {
-	parport_default_sysctl_table.sysctl_header =
-		register_sysctl_table(parport_default_sysctl_table.dev_dir);
+	parport_default_sysctl_header =
+		register_sysctl_paths(parport_default_path,
+				      parport_default_sysctl_table);
+	/* XXX: if this fails then we can't access the sysctl tables for
+	 * /proc/sys/dev/parport/default/. Should the module fail to load? */
 	return 0;
 }
 
 static void __exit parport_default_proc_unregister(void)
 {
-	if (parport_default_sysctl_table.sysctl_header) {
-		unregister_sysctl_table(parport_default_sysctl_table.
-					sysctl_header);
-		parport_default_sysctl_table.sysctl_header = NULL;
+	if (parport_default_sysctl_header) {
+		unregister_sysctl_table(parport_default_sysctl_header);
+		parport_default_sysctl_header = NULL;
 	}
 }
 
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 007/115] sysctl: remove .child from abi/vsyscall32 (x86)
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 arch/x86/vdso/vdso32-setup.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 468d591..e6ef3b4 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -380,7 +380,7 @@ subsys_initcall(sysenter_setup);
 /* Register vsyscall32 into the ABI table */
 #include <linux/sysctl.h>
 
-static ctl_table abi_table2[] = {
+static ctl_table abi_table[] = {
 	{
 		.procname	= "vsyscall32",
 		.data		= &sysctl_vsyscall32,
@@ -391,18 +391,14 @@ static ctl_table abi_table2[] = {
 	{}
 };
 
-static ctl_table abi_root_table2[] = {
-	{
-		.procname = "abi",
-		.mode = 0555,
-		.child = abi_table2
-	},
-	{}
+static const struct ctl_path abi_root_path[] = {
+	{ .procname = "abi" },
+	{ }
 };
 
 static __init int ia32_binfmt_init(void)
 {
-	register_sysctl_table(abi_root_table2);
+	register_sysctl_paths(abi_root_path, abi_table);
 	return 0;
 }
 __initcall(ia32_binfmt_init);
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 011/115] sysctl: remove .child from dev/ipmi/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 drivers/char/ipmi/ipmi_poweroff.c |   16 ++++------------
 1 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 2efa176..ac71d69 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -668,17 +668,9 @@ static ctl_table ipmi_table[] = {
 	{ }
 };
 
-static ctl_table ipmi_dir_table[] = {
-	{ .procname	= "ipmi",
-	  .mode		= 0555,
-	  .child	= ipmi_table },
-	{ }
-};
-
-static ctl_table ipmi_root_table[] = {
-	{ .procname	= "dev",
-	  .mode		= 0555,
-	  .child	= ipmi_dir_table },
+static const struct ctl_path ipmi_path[] = {
+	{ .procname = "dev" },
+	{ .procname = "ipmi" },
 	{ }
 };
 
@@ -699,7 +691,7 @@ static int __init ipmi_poweroff_init(void)
 		printk(KERN_INFO PFX "Power cycle is enabled.\n");
 
 #ifdef CONFIG_PROC_FS
-	ipmi_table_header = register_sysctl_table(ipmi_root_table);
+	ipmi_table_header = register_sysctl_paths(ipmi_path, ipmi_table);
 	if (!ipmi_table_header) {
 		printk(KERN_ERR PFX "Unable to register powercycle sysctl\n");
 		rv = -ENOMEM;
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 017/115] sysctl: remove .child from kernel/sclp (s390)
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 drivers/s390/char/sclp_async.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index 7ad30e7..43f8b1e 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -106,14 +106,9 @@ static struct ctl_table callhome_table[] = {
 	{}
 };
 
-static struct ctl_table kern_dir_table[] = {
-	{
-		.procname	= "kernel",
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= callhome_table,
-	},
-	{}
+static const __initdata struct ctl_path kern_path[] = {
+	{ .procname = "kernel" },
+	{ }
 };
 
 /*
@@ -175,7 +170,7 @@ static int __init sclp_async_init(void)
 	if (!(sclp_async_register.sclp_receive_mask & EVTYP_ASYNC_MASK))
 		goto out_sclp;
 	rc = -ENOMEM;
-	callhome_sysctl_header = register_sysctl_table(kern_dir_table);
+	callhome_sysctl_header = register_sysctl_paths(kern_path, callhome_table);
 	if (!callhome_sysctl_header)
 		goto out_sclp;
 	request = kzalloc(sizeof(struct sclp_req), GFP_KERNEL);
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 021/115] sysctl: remove .child from fscache/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 fs/fscache/main.c |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index f9d8567..7f9c055 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -67,7 +67,7 @@ static int fscache_max_active_sysctl(struct ctl_table *table, int write,
 	return ret;
 }
 
-ctl_table fscache_sysctls[] = {
+static ctl_table fscache_table[] = {
 	{
 		.procname	= "object_max_active",
 		.data		= &fscache_object_max_active,
@@ -87,14 +87,11 @@ ctl_table fscache_sysctls[] = {
 	{}
 };
 
-ctl_table fscache_sysctls_root[] = {
-	{
-		.procname	= "fscache",
-		.mode		= 0555,
-		.child		= fscache_sysctls,
-	},
-	{}
+static const __initdata struct ctl_path fscache_path[] = {
+	{ .procname = "fscache" },
+	{ }
 };
+
 #endif
 
 /*
@@ -135,7 +132,7 @@ static int __init fscache_init(void)
 
 #ifdef CONFIG_SYSCTL
 	ret = -ENOMEM;
-	fscache_sysctl_header = register_sysctl_table(fscache_sysctls_root);
+	fscache_sysctl_header = register_sysctl_paths(fscache_path, fscache_table);
 	if (!fscache_sysctl_header)
 		goto error_sysctl;
 #endif
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 025/115] sysctl: remove .child from fs/ocfs2/nm/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 fs/ocfs2/stackglue.c |   36 +++++-------------------------------
 1 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index 39abf89..3cb738a 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -654,36 +654,10 @@ static ctl_table ocfs2_nm_table[] = {
 	{ }
 };
 
-static ctl_table ocfs2_mod_table[] = {
-	{
-		.procname	= "nm",
-		.data		= NULL,
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= ocfs2_nm_table
-	},
-	{ }
-};
-
-static ctl_table ocfs2_kern_table[] = {
-	{
-		.procname	= "ocfs2",
-		.data		= NULL,
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= ocfs2_mod_table
-	},
-	{ }
-};
-
-static ctl_table ocfs2_root_table[] = {
-	{
-		.procname	= "fs",
-		.data		= NULL,
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= ocfs2_kern_table
-	},
+static const __initdata struct ctl_path ocfs2_nm_path[] = {
+	{ .procname = "fs" },
+	{ .procname = "ocfs2" },
+	{ .procname = "nm" },
 	{ }
 };
 
@@ -698,7 +672,7 @@ static int __init ocfs2_stack_glue_init(void)
 {
 	strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
 
-	ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
+	ocfs2_table_header = register_sysctl_paths(ocfs2_nm_path, ocfs2_nm_table);
 	if (!ocfs2_table_header) {
 		printk(KERN_ERR
 		       "ocfs2 stack glue: unable to register sysctl\n");
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 027/115] sysctl: remove .child from fs/xfs/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 fs/xfs/linux-2.6/xfs_sysctl.c |   22 +++++-----------------
 1 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index ee2d2ad..95f803c 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -218,28 +218,16 @@ static ctl_table xfs_table[] = {
 	{}
 };
 
-static ctl_table xfs_dir_table[] = {
-	{
-		.procname	= "xfs",
-		.mode		= 0555,
-		.child		= xfs_table
-	},
-	{}
-};
-
-static ctl_table xfs_root_table[] = {
-	{
-		.procname	= "fs",
-		.mode		= 0555,
-		.child		= xfs_dir_table
-	},
-	{}
+static const __initdata struct ctl_path xfs_path[] = {
+	{ .procname = "fs" },
+	{ .procname = "xfs" },
+	{ }
 };
 
 int
 xfs_sysctl_register(void)
 {
-	xfs_table_header = register_sysctl_table(xfs_root_table);
+	xfs_table_header = register_sysctl_paths(xfs_path, xfs_table);
 	if (!xfs_table_header)
 		return -ENOMEM;
 	return 0;
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 029/115] sysctl: remove .child from fs/mqueue
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 ipc/mq_sysctl.c |   24 ++++++------------------
 1 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c
index 0c09366..007164b 100644
--- a/ipc/mq_sysctl.c
+++ b/ipc/mq_sysctl.c
@@ -62,7 +62,7 @@ static int msg_max_limit_max = MAX_MSGMAX;
 static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
 static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
 
-static ctl_table mq_sysctls[] = {
+static ctl_table mq_table[] = {
 	{
 		.procname	= "queues_max",
 		.data		= &init_ipc_ns.mq_queues_max,
@@ -91,25 +91,13 @@ static ctl_table mq_sysctls[] = {
 	{}
 };
 
-static ctl_table mq_sysctl_dir[] = {
-	{
-		.procname	= "mqueue",
-		.mode		= 0555,
-		.child		= mq_sysctls,
-	},
-	{}
-};
-
-static ctl_table mq_sysctl_root[] = {
-	{
-		.procname	= "fs",
-		.mode		= 0555,
-		.child		= mq_sysctl_dir,
-	},
-	{}
+static const struct ctl_path mq_path[] = {
+	{ .procname = "fs" },
+	{ .procname = "mqueue" },
+	{ }
 };
 
 struct ctl_table_header *mq_register_sysctl_table(void)
 {
-	return register_sysctl_table(mq_sysctl_root);
+	return register_sysctl_paths(mq_path, mq_table);
 }
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 031/115] sysctl: remove .child from kernel/sched_domain/cpuX/domainY/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Note: this patch makes sure to add empty kernel/sched_domain/cpuX/
directories when there are no domains in them.

This was the behaviour before this patch, and I thought it may need to
remain so in the new implementation. If they are not necessary this
can be removed to simplify the code.

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 kernel/sched.c |  266 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 180 insertions(+), 86 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 23a980c..6e39b7c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6181,52 +6181,6 @@ static struct ctl_table sd_table_template[] = {
 	{ }
 };
 
-static struct ctl_table sd_ctl_dir[] = {
-	{
-		.procname	= "sched_domain",
-		.mode		= 0555,
-	},
-	{}
-};
-
-static struct ctl_table sd_ctl_root[] = {
-	{
-		.procname	= "kernel",
-		.mode		= 0555,
-		.child		= sd_ctl_dir,
-	},
-	{}
-};
-
-static struct ctl_table *sd_alloc_ctl_entry(int n)
-{
-	struct ctl_table *entry =
-		kcalloc(n, sizeof(struct ctl_table), GFP_KERNEL);
-
-	return entry;
-}
-
-static void sd_free_ctl_entry(struct ctl_table **tablep)
-{
-	struct ctl_table *entry;
-
-	/*
-	 * In the intermediate directories, both the child directory and
-	 * procname are dynamically allocated and could fail but the mode
-	 * will always be set. In the lowest directory the names are
-	 * static strings and all have proc handlers.
-	 */
-	for (entry = *tablep; entry->mode; entry++) {
-		if (entry->child)
-			sd_free_ctl_entry(&entry->child);
-		if (entry->proc_handler == NULL)
-			kfree(entry->procname);
-	}
-
-	kfree(*tablep);
-	*tablep = NULL;
-}
-
 static struct ctl_table *
 sd_alloc_ctl_domain_table(struct sched_domain *sd)
 {
@@ -6250,64 +6204,204 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
 	return table;
 }
 
-static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
+/*
+ * Find out what is the maximum number of domains in a cpu, and the
+ * total number of domains across all cpus.
+ */
+static void count_sd_domains(int *p_max, int *p_total)
 {
-	struct ctl_table *entry, *table;
-	struct sched_domain *sd;
-	int domain_num = 0, i;
-	char buf[32];
+	int cpu;
+	int max = 0;
+	int total = 0;
 
-	for_each_domain(cpu, sd)
-		domain_num++;
-	entry = table = sd_alloc_ctl_entry(domain_num + 1);
-	if (table == NULL)
-		return NULL;
+	for_each_possible_cpu(cpu) {
+		struct sched_domain *sd;
+		int domain_num = 0;
 
-	i = 0;
-	for_each_domain(cpu, sd) {
-		snprintf(buf, 32, "domain%d", i);
-		entry->procname = kstrdup(buf, GFP_KERNEL);
-		entry->mode = 0555;
-		entry->child = sd_alloc_ctl_domain_table(sd);
-		entry++;
-		i++;
+		for_each_domain(cpu, sd)
+			domain_num++;
+
+		if (domain_num > max)
+			max = domain_num;
+		total += domain_num;
 	}
-	return table;
+	*p_max = max;
+	*p_total = total;
 }
 
-static struct ctl_table_header *sd_sysctl_header;
+
+/* enough space to hold a string "cpu%d" or "domain%d" */
+#define SD_NAME_LEN 32
+typedef char sd_name_buf[SD_NAME_LEN];
+
+static sd_name_buf *sd_cpu_names, *sd_domain_names;
+static int sd_domain_headers_num, sd_cpudir_headers_num;
+static struct ctl_table_header **sd_domain_headers, **sd_cpudir_headers;
+
 static void register_sched_domain_sysctl(void)
 {
-	int i, cpu_num = num_possible_cpus();
-	struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
-	char buf[32];
+	int cpu, i;
+	int cpu_num, max_domain_num;
+
+	/* possitions 2 and 3 in the array bellow */
+#define SD_PATH_CPU 2
+#define SD_PATH_DOM 3
+	struct ctl_path sd_path[] = {
+		{ .procname = "kernel" },
+		{ .procname = "sched_domain" },
+		{ /* 'cpu0' */ },
+		{ /* 'domain0' */ },
+		{  },
+	};
 
-	WARN_ON(sd_ctl_dir[0].child);
-	sd_ctl_dir[0].child = entry;
+	sd_cpudir_headers_num = cpu_num = num_possible_cpus();
+	count_sd_domains(&max_domain_num, &sd_domain_headers_num);
 
-	if (entry == NULL)
-		return;
+	/*
+	 * Allocate space for:
+	 * - all cpu names (cpu0, cpu1,...) and all domain names (domain0,...)
+	 * - the array of headers for cpu dirs    kernel/sched_domain/cpuX/
+	 * - the array of headers for domain dirs kernel/sched_domain/cpuX/domainY
+	 *
+	 * We only register the empty kernel/sched_domain/cpuX/ dirs
+	 * to not break the ABI: if there were no domains defined, we
+	 * would still have empty cpuX dir entries in
+	 * kernel/sched_domain/.
+	 *
+	 * If this is not considered useful or part of the ABI, then
+	 * we can drop the empty cpu dir entries.
+	 */
+	sd_cpu_names = kmalloc(sizeof(sd_name_buf) * cpu_num, GFP_KERNEL);
+	if (sd_cpu_names == NULL)
+		goto fail_alloc_sd_cpu_names;
 
-	for_each_possible_cpu(i) {
-		snprintf(buf, 32, "cpu%d", i);
-		entry->procname = kstrdup(buf, GFP_KERNEL);
-		entry->mode = 0555;
-		entry->child = sd_alloc_ctl_cpu_table(i);
-		entry++;
+	sd_domain_names = kmalloc(sizeof(sd_name_buf) * max_domain_num, GFP_KERNEL);
+	if (sd_domain_names == NULL)
+		goto fail_alloc_sd_domain_names;
+
+	sd_cpudir_headers = kmalloc(sizeof(*sd_cpudir_headers) *
+				    sd_cpudir_headers_num, GFP_KERNEL);
+	if (sd_cpudir_headers == NULL)
+		goto fail_alloc_sd_cpudir_headers;
+
+	sd_domain_headers = kmalloc(sizeof(*sd_domain_headers) *
+				    sd_domain_headers_num, GFP_KERNEL);
+	if (sd_domain_headers == NULL)
+		goto fail_alloc_sd_domain_headers;
+
+	for_each_possible_cpu(cpu)
+		snprintf((char*)&sd_cpu_names[cpu], SD_NAME_LEN, "cpu%d", cpu);
+	for (i = 0; i < max_domain_num; i++)
+		snprintf((char*)&sd_domain_names[i], SD_NAME_LEN, "domain%d", i);
+
+	i = 0;
+	for_each_possible_cpu(cpu) {
+		struct ctl_table *empty = kzalloc(sizeof(*empty), GFP_KERNEL);
+		if (empty == NULL)
+			goto unregister_sd_cpudir_headers;
+		sd_path[SD_PATH_CPU].procname = sd_cpu_names[cpu];
+		sd_path[SD_PATH_DOM].procname = NULL; /* end of array sentinel */
+		sd_cpudir_headers[i] = register_sysctl_paths(sd_path, empty);
+		if (sd_cpudir_headers[i] == NULL) {
+			kfree(empty);
+			goto unregister_sd_cpudir_headers;
+		}
+		i++;
+	}
+
+	i = 0;
+	for_each_possible_cpu(cpu) {
+		struct sched_domain *sd;
+		int domain = 0;
+		for_each_domain(cpu, sd) {
+			struct ctl_table *table = sd_alloc_ctl_domain_table(sd);
+			if (table == NULL)
+				goto unregister_sd_domain_headers;
+			sd_path[SD_PATH_CPU].procname = sd_cpu_names[cpu];
+			sd_path[SD_PATH_DOM].procname = sd_domain_names[domain];
+			sd_domain_headers[i] = register_sysctl_paths(sd_path, table);
+			if (sd_domain_headers[i] == NULL) {
+				kfree(table);
+				goto unregister_sd_domain_headers;
+			}
+			i++;
+			domain++;
+		}
 	}
 
-	WARN_ON(sd_sysctl_header);
-	sd_sysctl_header = register_sysctl_table(sd_ctl_root);
+	return;
+
+unregister_sd_domain_headers:
+	i--; /* the current 'i' was being filled in, but fail_alloced */
+	for(; i >= 0; i--) {
+		struct ctl_table *table = sd_domain_headers[i]->ctl_table_arg;
+		unregister_sysctl_table(sd_domain_headers[i]);
+		kfree(table);
+	}
+	i = sd_cpudir_headers_num;
+unregister_sd_cpudir_headers:
+	i--;
+	for(; i >= 0; i--) {
+		struct ctl_table *table = sd_cpudir_headers[i]->ctl_table_arg;
+		unregister_sysctl_table(sd_cpudir_headers[i]);
+		kfree(table);
+	}
+
+	kfree(sd_domain_headers);
+fail_alloc_sd_domain_headers:
+	kfree(sd_cpudir_headers);
+fail_alloc_sd_cpudir_headers:
+	kfree(sd_domain_names);
+fail_alloc_sd_domain_names:
+	kfree(sd_cpu_names);
+fail_alloc_sd_cpu_names:
+	sd_domain_headers = NULL;
+	sd_cpudir_headers = NULL;
+	sd_domain_names = NULL;
+	sd_cpu_names = NULL;
+	sd_domain_headers_num = 0;
+	sd_cpudir_headers_num = 0;
 }
 
 /* may be called multiple times per register */
 static void unregister_sched_domain_sysctl(void)
 {
-	if (sd_sysctl_header)
-		unregister_sysctl_table(sd_sysctl_header);
-	sd_sysctl_header = NULL;
-	if (sd_ctl_dir[0].child)
-		sd_free_ctl_entry(&sd_ctl_dir[0].child);
+	int i;
+
+	/* because this function may be called multiple times (not
+	 * concurrently) for a single register_sched_domain_sysctl call,
+	 * we skip unregistering if it was already done by a previous
+	 * call. This is also why we make sure to NULLify all
+	 * pointers: make sure nothing is double-freed. */
+	if (sd_domain_headers == NULL)
+		return;
+
+	/* unregister in the reverse order of registering, or we'll
+	 * get a harmless warning saying that the parent of a header
+	 * was registered before all it's children. */
+	for(i = sd_domain_headers_num - 1; i >= 0; i--) {
+		struct ctl_table *table = sd_domain_headers[i]->ctl_table_arg;
+		unregister_sysctl_table(sd_domain_headers[i]);
+		kfree(table);
+	}
+
+	for(i = sd_cpudir_headers_num - 1; i >= 0; i--) {
+		struct ctl_table *table = sd_cpudir_headers[i]->ctl_table_arg;
+		unregister_sysctl_table(sd_cpudir_headers[i]);
+		kfree(table);
+	}
+
+	kfree(sd_domain_headers);
+	kfree(sd_cpudir_headers);
+	kfree(sd_domain_names);
+	kfree(sd_cpu_names);
+
+	sd_domain_headers = NULL;
+	sd_cpudir_headers = NULL;
+	sd_domain_names = NULL;
+	sd_cpu_names = NULL;
+	sd_cpudir_headers_num = 0;
+	sd_domain_headers_num = 0;
 }
 #else
 static void register_sched_domain_sysctl(void)
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 033/115] sysctl: remove .child from sunrpc/
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 net/sunrpc/sysctl.c |   19 +++++++------------
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index e65dcc6..7450ab2 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -38,13 +38,17 @@ EXPORT_SYMBOL_GPL(nlm_debug);
 #ifdef RPC_DEBUG
 
 static struct ctl_table_header *sunrpc_table_header;
-static ctl_table		sunrpc_table[];
+static ctl_table sunrpc_table[];
+static const struct ctl_path sunrpc_path[] = {
+	{ .procname = "sunrpc" },
+	{ }
+};
 
 void
 rpc_register_sysctl(void)
 {
 	if (!sunrpc_table_header)
-		sunrpc_table_header = register_sysctl_table(sunrpc_table);
+		sunrpc_table_header = register_sysctl_paths(sunrpc_path, sunrpc_table);
 }
 
 void
@@ -133,7 +137,7 @@ done:
 }
 
 
-static ctl_table debug_table[] = {
+static ctl_table sunrpc_table[] = {
 	{
 		.procname	= "rpc_debug",
 		.data		= &rpc_debug,
@@ -171,13 +175,4 @@ static ctl_table debug_table[] = {
 	{ }
 };
 
-static ctl_table sunrpc_table[] = {
-	{
-		.procname	= "sunrpc",
-		.mode		= 0555,
-		.child		= debug_table
-	},
-	{ }
-};
-
 #endif
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* Re: [v2 000/115] faster tree-based sysctl implementation
From: David Miller @ 2011-05-08 22:40 UTC (permalink / raw)
  To: lucian.grijincu; +Cc: linux-kernel, netdev, ebiederm, adobriyan, tavi
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

From: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
Date: Mon,  9 May 2011 00:38:12 +0200

> This patch series introduces a faster/leaner sysctl internal implementation:

NO WAY.

Do not send so many patches all at once, never do anything like
that, it's too much.

^ permalink raw reply

* [v2 042/115] sysctl: remove .child from vm/ (s390)
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 arch/s390/mm/cmm.c |   11 +++--------
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index c66ffd8..0ef5bbf 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -348,13 +348,8 @@ static struct ctl_table cmm_table[] = {
 	{ }
 };
 
-static struct ctl_table cmm_dir_table[] = {
-	{
-		.procname	= "vm",
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= cmm_table,
-	},
+static const __initdata struct ctl_path cmm_path[] = {
+	{ .procname = "vm" },
 	{ }
 };
 
@@ -434,7 +429,7 @@ static int __init cmm_init(void)
 {
 	int rc = -ENOMEM;
 
-	cmm_sysctl_header = register_sysctl_table(cmm_dir_table);
+	cmm_sysctl_header = register_sysctl_paths(cmm_path, cmm_table);
 	if (!cmm_sysctl_header)
 		goto out_sysctl;
 #ifdef CONFIG_CMM_IUCV
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 045/115] sysctl: remove .child from kernel/powersave-nap (powerpc)
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 arch/powerpc/kernel/idle.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 39a2baa..88d03c5 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -118,19 +118,16 @@ static ctl_table powersave_nap_ctl_table[]={
 	},
 	{}
 };
-static ctl_table powersave_nap_sysctl_root[] = {
-	{
-		.procname	= "kernel",
-		.mode		= 0555,
-		.child		= powersave_nap_ctl_table,
-	},
-	{}
+
+static const __initdata struct ctl_path powersave_nap_path[] = {
+	{ .procname = "kernel" },
+	{ }
 };
 
 static int __init
 register_powersave_nap_sysctl(void)
 {
-	register_sysctl_table(powersave_nap_sysctl_root);
+	register_sysctl_paths(powersave_nap_path, powersave_nap_ctl_table);
 
 	return 0;
 }
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 046/115] sysctl: remove .child from pm/ (frv)
From: Lucian Adrian Grijincu @ 2011-05-08 22:38 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev, Lucian Adrian Grijincu
In-Reply-To: <1304894407-32201-1-git-send-email-lucian.grijincu@gmail.com>

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 arch/frv/kernel/pm.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 5fa3889..bcef945 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -329,13 +329,9 @@ static struct ctl_table pm_table[] =
 	{ }
 };
 
-static struct ctl_table pm_dir_table[] =
+static const __initdata struct ctl_path pm_path[] =
 {
-	{
-		.procname	= "pm",
-		.mode		= 0555,
-		.child		= pm_table,
-	},
+	{ .procname = "pm" },
 	{ }
 };
 
@@ -344,7 +340,7 @@ static struct ctl_table pm_dir_table[] =
  */
 static int __init pm_init(void)
 {
-	register_sysctl_table(pm_dir_table);
+	register_sysctl_paths(pm_path, pm_table);
 	return 0;
 }
 
-- 
1.7.5.134.g1c08b


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox