aboutsummaryrefslogtreecommitdiffstats
path: root/net/ax25
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-04-19 09:34:18 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-20 21:22:28 -0400
commit0ca7a4c87d27dd2fde0783dec94a821d6d035696 (patch)
tree3f9d1cd9a8146ce751e43f8f103a255fc7ec199d /net/ax25
parent4e5ca78541c549ec8886ad2fc19306f35ee672e1 (diff)
net ax25: Simplify and cleanup the ax25 sysctl handling.
Don't register/unregister every ax25 table in a batch. Instead register and unregister per device ax25 sysctls as ax25 devices come and go. This moves ax25 to be a completely modern sysctl user. Registering the sysctls in just the initial network namespace, removing the use of .child entries that are no longer natively supported by the sysctl core and taking advantage of the fact that there are no longer any ordering constraints between registering and unregistering different sysctl tables. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Acked-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ax25')
-rw-r--r--net/ax25/af_ax25.c2
-rw-r--r--net/ax25/ax25_dev.c10
-rw-r--r--net/ax25/sysctl_net_ax25.c82
3 files changed, 30 insertions, 64 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 0906c194a413..282eb76bc7d6 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1990,7 +1990,6 @@ static int __init ax25_init(void)
1990 sock_register(&ax25_family_ops); 1990 sock_register(&ax25_family_ops);
1991 dev_add_pack(&ax25_packet_type); 1991 dev_add_pack(&ax25_packet_type);
1992 register_netdevice_notifier(&ax25_dev_notifier); 1992 register_netdevice_notifier(&ax25_dev_notifier);
1993 ax25_register_sysctl();
1994 1993
1995 proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops); 1994 proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
1996 proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops); 1995 proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
@@ -2015,7 +2014,6 @@ static void __exit ax25_exit(void)
2015 ax25_uid_free(); 2014 ax25_uid_free();
2016 ax25_dev_free(); 2015 ax25_dev_free();
2017 2016
2018 ax25_unregister_sysctl();
2019 unregister_netdevice_notifier(&ax25_dev_notifier); 2017 unregister_netdevice_notifier(&ax25_dev_notifier);
2020 2018
2021 dev_remove_pack(&ax25_packet_type); 2019 dev_remove_pack(&ax25_packet_type);
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index d0de30e89591..3d106767b272 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -59,8 +59,6 @@ void ax25_dev_device_up(struct net_device *dev)
59 return; 59 return;
60 } 60 }
61 61
62 ax25_unregister_sysctl();
63
64 dev->ax25_ptr = ax25_dev; 62 dev->ax25_ptr = ax25_dev;
65 ax25_dev->dev = dev; 63 ax25_dev->dev = dev;
66 dev_hold(dev); 64 dev_hold(dev);
@@ -90,7 +88,7 @@ void ax25_dev_device_up(struct net_device *dev)
90 ax25_dev_list = ax25_dev; 88 ax25_dev_list = ax25_dev;
91 spin_unlock_bh(&ax25_dev_lock); 89 spin_unlock_bh(&ax25_dev_lock);
92 90
93 ax25_register_sysctl(); 91 ax25_register_dev_sysctl(ax25_dev);
94} 92}
95 93
96void ax25_dev_device_down(struct net_device *dev) 94void ax25_dev_device_down(struct net_device *dev)
@@ -100,7 +98,7 @@ void ax25_dev_device_down(struct net_device *dev)
100 if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) 98 if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
101 return; 99 return;
102 100
103 ax25_unregister_sysctl(); 101 ax25_unregister_dev_sysctl(ax25_dev);
104 102
105 spin_lock_bh(&ax25_dev_lock); 103 spin_lock_bh(&ax25_dev_lock);
106 104
@@ -120,7 +118,6 @@ void ax25_dev_device_down(struct net_device *dev)
120 spin_unlock_bh(&ax25_dev_lock); 118 spin_unlock_bh(&ax25_dev_lock);
121 dev_put(dev); 119 dev_put(dev);
122 kfree(ax25_dev); 120 kfree(ax25_dev);
123 ax25_register_sysctl();
124 return; 121 return;
125 } 122 }
126 123
@@ -130,7 +127,6 @@ void ax25_dev_device_down(struct net_device *dev)
130 spin_unlock_bh(&ax25_dev_lock); 127 spin_unlock_bh(&ax25_dev_lock);
131 dev_put(dev); 128 dev_put(dev);
132 kfree(ax25_dev); 129 kfree(ax25_dev);
133 ax25_register_sysctl();
134 return; 130 return;
135 } 131 }
136 132
@@ -138,8 +134,6 @@ void ax25_dev_device_down(struct net_device *dev)
138 } 134 }
139 spin_unlock_bh(&ax25_dev_lock); 135 spin_unlock_bh(&ax25_dev_lock);
140 dev->ax25_ptr = NULL; 136 dev->ax25_ptr = NULL;
141
142 ax25_register_sysctl();
143} 137}
144 138
145int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd) 139int 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 7ba381b6f074..d5744b752511 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 };
29static int min_ds_timeout[1], max_ds_timeout[] = {65535000}; 29static int min_ds_timeout[1], max_ds_timeout[] = {65535000};
30#endif 30#endif
31 31
32static struct ctl_table_header *ax25_table_header;
33
34static ctl_table *ax25_table;
35static int ax25_table_size;
36
37static struct ctl_path ax25_path[] = {
38 { .procname = "net", },
39 { .procname = "ax25", },
40 { }
41};
42
43static const ctl_table ax25_param_table[] = { 32static const ctl_table ax25_param_table[] = {
44 { 33 {
45 .procname = "ip_default_mode", 34 .procname = "ip_default_mode",
@@ -159,52 +148,37 @@ static const ctl_table ax25_param_table[] = {
159 { } /* that's all, folks! */ 148 { } /* that's all, folks! */
160}; 149};
161 150
162void ax25_register_sysctl(void) 151int ax25_register_dev_sysctl(ax25_dev *ax25_dev)
163{ 152{
164 ax25_dev *ax25_dev; 153 char path[sizeof("net/ax25/") + IFNAMSIZ];
165 int n, k; 154 int k;
166 155 struct ctl_table *table;
167 spin_lock_bh(&ax25_dev_lock); 156
168 for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) 157 table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
169 ax25_table_size += sizeof(ctl_table); 158 if (!table)
170 159 return -ENOMEM;
171 if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) { 160
172 spin_unlock_bh(&ax25_dev_lock); 161 for (k = 0; k < AX25_MAX_VALUES; k++)
173 return; 162 table[k].data = &ax25_dev->values[k];
174 } 163
175 164 snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name);
176 for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { 165 ax25_dev->sysheader = register_net_sysctl(&init_net, path, table);
177 struct ctl_table *child = kmemdup(ax25_param_table, 166 if (!ax25_dev->sysheader) {
178 sizeof(ax25_param_table), 167 kfree(table);
179 GFP_ATOMIC); 168 return -ENOMEM;
180 if (!child) {
181 while (n--)
182 kfree(ax25_table[n].child);
183 kfree(ax25_table);
184 spin_unlock_bh(&ax25_dev_lock);
185 return;
186 }
187 ax25_table[n].child = ax25_dev->systable = child;
188 ax25_table[n].procname = ax25_dev->dev->name;
189 ax25_table[n].mode = 0555;
190
191
192 for (k = 0; k < AX25_MAX_VALUES; k++)
193 child[k].data = &ax25_dev->values[k];
194
195 n++;
196 } 169 }
197 spin_unlock_bh(&ax25_dev_lock); 170 return 0;
198
199 ax25_table_header = register_net_sysctl_table(&init_net, ax25_path, ax25_table);
200} 171}
201 172
202void ax25_unregister_sysctl(void) 173void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev)
203{ 174{
204 ctl_table *p; 175 struct ctl_table_header *header = ax25_dev->sysheader;
205 unregister_net_sysctl_table(ax25_table_header); 176 struct ctl_table *table;
206 177
207 for (p = ax25_table; p->procname; p++) 178 if (header) {
208 kfree(p->child); 179 ax25_dev->sysheader = NULL;
209 kfree(ax25_table); 180 table = header->ctl_table_arg;
181 unregister_net_sysctl_table(header);
182 kfree(table);
183 }
210} 184}