Netdev List
 help / color / mirror / Atom feed
* [v2 054/115] sysctl: remove .child from net/llc tables
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/llc/sysctl_net_llc.c |   55 +++++++++++++++++++++++----------------------
 1 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c
index e2ebe35..8977307 100644
--- a/net/llc/sysctl_net_llc.c
+++ b/net/llc/sysctl_net_llc.c
@@ -56,48 +56,49 @@ static struct ctl_table llc_station_table[] = {
 	{ },
 };
 
-static struct ctl_table llc2_dir_timeout_table[] = {
-	{
-		.procname	= "timeout",
-		.mode		= 0555,
-		.child		= llc2_timeout_table,
-	},
-	{ },
-};
 
-static struct ctl_table llc_table[] = {
-	{
-		.procname	= "llc2",
-		.mode		= 0555,
-		.child		= llc2_dir_timeout_table,
-	},
-	{
-		.procname       = "station",
-		.mode           = 0555,
-		.child          = llc_station_table,
-	},
-	{ },
+static const __initdata struct ctl_path llc2_timeout_path[] = {
+	{ .procname = "net", },
+	{ .procname = "llc", },
+	{ .procname = "llc2", },
+	{ .procname = "timeout", },
+	{ }
 };
 
-static struct ctl_path llc_path[] = {
+static const __initdata struct ctl_path llc_station_path[] = {
 	{ .procname = "net", },
 	{ .procname = "llc", },
+	{ .procname = "station", },
 	{ }
 };
 
-static struct ctl_table_header *llc_table_header;
+static struct ctl_table_header *llc_station_hdr;
+static struct ctl_table_header *llc2_timeout_hdr;
 
 int __init llc_sysctl_init(void)
 {
-	llc_table_header = register_sysctl_paths(llc_path, llc_table);
+	llc_station_hdr = register_sysctl_paths(llc_station_path, llc_station_table);
+	if (!llc_station_hdr)
+		return -ENOMEM;
 
-	return llc_table_header ? 0 : -ENOMEM;
+	llc2_timeout_hdr = register_sysctl_paths(llc2_timeout_path, llc2_timeout_table);
+	if (!llc2_timeout_hdr) {
+		unregister_sysctl_table(llc_station_hdr);
+		llc_station_hdr = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
 void llc_sysctl_exit(void)
 {
-	if (llc_table_header) {
-		unregister_sysctl_table(llc_table_header);
-		llc_table_header = NULL;
+	if (llc2_timeout_hdr) {
+		unregister_sysctl_table(llc2_timeout_hdr);
+		llc2_timeout_hdr = NULL;
+	}
+	if (llc_station_hdr) {
+		unregister_sysctl_table(llc_station_hdr);
+		llc_station_hdr = NULL;
 	}
 }
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 050/115] sysctl: remove .child from ax25 table
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>

Only compile tested!

I'm sorry but I could not manage to add a ax25 interface.

Some notable changes: before this patch, each time a device switched
to up/down we would unregister everything under /proc/sys/net/ax25/
and then reregister an updated table with all devices in it (BTW, the
table was GFP_ATOMIC!).

Now each state change (up/down) registers it's own table (e.g.
/proc/sys/net/ax25/ax0/). I'm assuming ax25 devices cannot be renamed,
but if that's possible, this can be fixed by making a private copy of
the device name for sysctl, and unregistering/reregistering the table
on device rename (see net/ipv4/devinet.c).

Also added an empty /proc/sys/net/ax25/ root directory. Without it,
the first device added would have been the first to create the
/proc/sys/net/ax25/ sysctl path and all other devices would have
attached to it. If the first device was to be removed before other
ones, we would have gotten a harmless warning form sysctl telling us
we're unregistering the parent before the children.

Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
---
 include/net/ax25.h         |   10 +++---
 net/ax25/af_ax25.c         |   23 ++++++++++++-
 net/ax25/ax25_dev.c        |   10 +-----
 net/ax25/sysctl_net_ax25.c |   76 ++++++++++++++-----------------------------
 4 files changed, 53 insertions(+), 66 deletions(-)

diff --git a/include/net/ax25.h b/include/net/ax25.h
index 206d222..79c2d2d 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -215,7 +215,7 @@ typedef struct ax25_dev {
 	struct ax25_dev		*next;
 	struct net_device	*dev;
 	struct net_device	*forward;
-	struct ctl_table	*systable;
+	struct ctl_table_header	*ax25_sysheader;
 	int			values[AX25_MAX_VALUES];
 #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
 	ax25_dama_info		dama;
@@ -441,11 +441,11 @@ extern void ax25_uid_free(void);
 
 /* sysctl_net_ax25.c */
 #ifdef CONFIG_SYSCTL
-extern void ax25_register_sysctl(void);
-extern void ax25_unregister_sysctl(void);
+extern void ax25_register_sysctl(struct ax25_dev *dev);
+extern void ax25_unregister_sysctl(struct ax25_dev *dev);
 #else
-static inline void ax25_register_sysctl(void) {};
-static inline void ax25_unregister_sysctl(void) {};
+static inline void ax25_register_sysctl(struct ax25_dev *dev) {};
+static inline void ax25_unregister_sysctl(struct ax25_dev *dev) {};
 #endif /* CONFIG_SYSCTL */
 
 #endif
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6da5dae..965662d 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1989,6 +1989,18 @@ static struct notifier_block ax25_dev_notifier = {
 	.notifier_call =ax25_device_event,
 };
 
+
+#ifdef CONFIG_SYSCTL
+static const struct __initdata ctl_path ax25_path[] = {
+	{ .procname = "net" },
+	{ .procname = "ax25" },
+	{ }
+};
+static struct ctl_table empty;
+static struct ctl_table_header *ax25_root_header;
+#endif /* CONFIG_SYSCTL */
+
+
 static int __init ax25_init(void)
 {
 	int rc = proto_register(&ax25_proto, 0);
@@ -1999,7 +2011,11 @@ static int __init ax25_init(void)
 	sock_register(&ax25_family_ops);
 	dev_add_pack(&ax25_packet_type);
 	register_netdevice_notifier(&ax25_dev_notifier);
-	ax25_register_sysctl();
+
+	/* XXX: no error checking done in initializer */
+	#ifdef CONFIG_SYSCTL
+	ax25_root_header = register_sysctl_paths(ax25_path, &empty);
+	#endif
 
 	proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
 	proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
@@ -2024,7 +2040,10 @@ static void __exit ax25_exit(void)
 	ax25_uid_free();
 	ax25_dev_free();
 
-	ax25_unregister_sysctl();
+	#ifdef CONFIG_SYSCTL
+	unregister_sysctl_table(ax25_root_header);
+	#endif
+
 	unregister_netdevice_notifier(&ax25_dev_notifier);
 
 	dev_remove_pack(&ax25_packet_type);
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index c1cb982..6ff1853 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -60,8 +60,6 @@ void ax25_dev_device_up(struct net_device *dev)
 		return;
 	}
 
-	ax25_unregister_sysctl();
-
 	dev->ax25_ptr     = ax25_dev;
 	ax25_dev->dev     = dev;
 	dev_hold(dev);
@@ -91,7 +89,7 @@ void ax25_dev_device_up(struct net_device *dev)
 	ax25_dev_list  = ax25_dev;
 	spin_unlock_bh(&ax25_dev_lock);
 
-	ax25_register_sysctl();
+	ax25_register_sysctl(ax25_dev);
 }
 
 void ax25_dev_device_down(struct net_device *dev)
@@ -101,7 +99,7 @@ void ax25_dev_device_down(struct net_device *dev)
 	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
 		return;
 
-	ax25_unregister_sysctl();
+	ax25_unregister_sysctl(ax25_dev);
 
 	spin_lock_bh(&ax25_dev_lock);
 
@@ -121,7 +119,6 @@ void ax25_dev_device_down(struct net_device *dev)
 		spin_unlock_bh(&ax25_dev_lock);
 		dev_put(dev);
 		kfree(ax25_dev);
-		ax25_register_sysctl();
 		return;
 	}
 
@@ -131,7 +128,6 @@ void ax25_dev_device_down(struct net_device *dev)
 			spin_unlock_bh(&ax25_dev_lock);
 			dev_put(dev);
 			kfree(ax25_dev);
-			ax25_register_sysctl();
 			return;
 		}
 
@@ -139,8 +135,6 @@ void ax25_dev_device_down(struct net_device *dev)
 	}
 	spin_unlock_bh(&ax25_dev_lock);
 	dev->ax25_ptr = NULL;
-
-	ax25_register_sysctl();
 }
 
 int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
index ebe0ef3..b1181bc 100644
--- a/net/ax25/sysctl_net_ax25.c
+++ b/net/ax25/sysctl_net_ax25.c
@@ -29,17 +29,6 @@ static int min_proto[1],		max_proto[] = { AX25_PROTO_MAX };
 static int min_ds_timeout[1],		max_ds_timeout[] = {65535000};
 #endif
 
-static struct ctl_table_header *ax25_table_header;
-
-static ctl_table *ax25_table;
-static int ax25_table_size;
-
-static struct ctl_path ax25_path[] = {
-	{ .procname = "net", },
-	{ .procname = "ax25", },
-	{ }
-};
-
 static const ctl_table ax25_param_table[] = {
 	{
 		.procname	= "ip_default_mode",
@@ -159,52 +148,37 @@ static const ctl_table ax25_param_table[] = {
 	{ }	/* that's all, folks! */
 };
 
-void ax25_register_sysctl(void)
+void ax25_register_sysctl(struct ax25_dev *ax25_dev)
 {
-	ax25_dev *ax25_dev;
-	int n, k;
-
-	spin_lock_bh(&ax25_dev_lock);
-	for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
-		ax25_table_size += sizeof(ctl_table);
-
-	if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) {
-		spin_unlock_bh(&ax25_dev_lock);
+	struct ctl_table *ax25_table;
+	int i;
+
+	/* Assuming the name does not change while this sysctl
+	 * is registered. If ax25 supports device renaming
+	 * (SIOCSIFNAME), sysctl will need it's own copy of
+	 * the name */
+	struct ctl_path ax25_path[] = {
+		{ .procname = "net" },
+		{ .procname = "ax25" },
+		{ .procname = ax25_dev->dev->name },
+		{ }
+	};
+
+
+	ax25_table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
+	if (!ax25_table)
 		return;
-	}
-
-	for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
-		struct ctl_table *child = kmemdup(ax25_param_table,
-						  sizeof(ax25_param_table),
-						  GFP_ATOMIC);
-		if (!child) {
-			while (n--)
-				kfree(ax25_table[n].child);
-			kfree(ax25_table);
-			spin_unlock_bh(&ax25_dev_lock);
-			return;
-		}
-		ax25_table[n].child = ax25_dev->systable = child;
-		ax25_table[n].procname     = ax25_dev->dev->name;
-		ax25_table[n].mode         = 0555;
-
 
-		for (k = 0; k < AX25_MAX_VALUES; k++)
-			child[k].data = &ax25_dev->values[k];
+	for (i = 0; i < AX25_MAX_VALUES; i++)
+		ax25_table[i].data = &ax25_dev->values[i];
 
-		n++;
-	}
-	spin_unlock_bh(&ax25_dev_lock);
-
-	ax25_table_header = register_sysctl_paths(ax25_path, ax25_table);
+	ax25_dev->ax25_sysheader = register_sysctl_paths(ax25_path, ax25_table);
 }
 
-void ax25_unregister_sysctl(void)
+void ax25_unregister_sysctl(struct ax25_dev *ax25_dev)
 {
-	ctl_table *p;
-	unregister_sysctl_table(ax25_table_header);
-
-	for (p = ax25_table; p->procname; p++)
-		kfree(p->child);
+	struct ctl_table *ax25_table = ax25_dev->ax25_sysheader->ctl_table_arg;
+	unregister_sysctl_table(ax25_dev->ax25_sysheader);
+	ax25_dev->ax25_sysheader = NULL;
 	kfree(ax25_table);
 }
-- 
1.7.5.134.g1c08b


^ permalink raw reply related

* [v2 049/115] sysctl: delete unused register_sysctl_table function
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 |    3 +--
 kernel/sysctl.c        |   26 ++------------------------
 2 files changed, 3 insertions(+), 26 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 11684d9..470e06a 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -985,7 +985,7 @@ extern int proc_do_large_bitmap(struct ctl_table *, int,
 				void __user *, size_t *, loff_t *);
 
 /*
- * Register a set of sysctl names by calling register_sysctl_table
+ * Register a set of sysctl names by calling __register_sysctl_paths
  * with an initialised array of struct ctl_table's.  An entry with 
  * NULL procname terminates the table.  table->de will be
  * set up by the registration and need not be initialised in advance.
@@ -1065,7 +1065,6 @@ void register_sysctl_root(struct ctl_table_root *root);
 struct ctl_table_header *__register_sysctl_paths(
 	struct ctl_table_root *root, struct nsproxy *namespaces,
 	const struct ctl_path *path, struct ctl_table *table);
-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);
 
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c0bb324..b813724 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1905,7 +1905,7 @@ struct ctl_table_header *__register_sysctl_paths(
 }
 
 /**
- * register_sysctl_table_path - register a sysctl table hierarchy
+ * register_sysctl_paths - register a sysctl table hierarchy
  * @path: The path to the directory the sysctl table is in.
  * @table: the top-level table structure
  *
@@ -1922,24 +1922,8 @@ struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
 }
 
 /**
- * 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);
-}
-
-/**
  * unregister_sysctl_table - unregister a sysctl table hierarchy
- * @header: the header returned from register_sysctl_table
+ * @header: the header returned from __register_sysctl_paths
  *
  * Unregisters the sysctl table and all children. proc entries may not
  * actually be removed until they are no longer used by anyone.
@@ -1987,11 +1971,6 @@ void setup_sysctl_set(struct ctl_table_set *p,
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
-{
-	return NULL;
-}
-
 struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
 						    struct ctl_table *table)
 {
@@ -2977,6 +2956,5 @@ EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
-EXPORT_SYMBOL(register_sysctl_table);
 EXPORT_SYMBOL(register_sysctl_paths);
 EXPORT_SYMBOL(unregister_sysctl_table);
-- 
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

* [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 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

* 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 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

* [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 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 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 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 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 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 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 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 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

* 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 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

* [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 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 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 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 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 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


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