Showing error 1554

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: net/x25/x25_proc.c
Line in file: 195
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

  1/*
  2 *        X.25 Packet Layer release 002
  3 *
  4 *        This is ALPHA test software. This code may break your machine,
  5 *        randomly fail to work with new releases, misbehave and/or generally
  6 *        screw up. It might even work.
  7 *
  8 *        This code REQUIRES 2.4 with seq_file support
  9 *
 10 *        This module:
 11 *                This module is free software; you can redistribute it and/or
 12 *                modify it under the terms of the GNU General Public License
 13 *                as published by the Free Software Foundation; either version
 14 *                2 of the License, or (at your option) any later version.
 15 *
 16 *        History
 17 *        2002/10/06        Arnaldo Carvalho de Melo  seq_file support
 18 */
 19
 20#include <linux/init.h>
 21#include <linux/proc_fs.h>
 22#include <linux/seq_file.h>
 23#include <net/net_namespace.h>
 24#include <net/sock.h>
 25#include <net/x25.h>
 26
 27#ifdef CONFIG_PROC_FS
 28static __inline__ struct x25_route *x25_get_route_idx(loff_t pos)
 29{
 30        struct list_head *route_entry;
 31        struct x25_route *rt = NULL;
 32
 33        list_for_each(route_entry, &x25_route_list) {
 34                rt = list_entry(route_entry, struct x25_route, node);
 35                if (!pos--)
 36                        goto found;
 37        }
 38        rt = NULL;
 39found:
 40        return rt;
 41}
 42
 43static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
 44        __acquires(x25_route_list_lock)
 45{
 46        loff_t l = *pos;
 47
 48        read_lock_bh(&x25_route_list_lock);
 49        return l ? x25_get_route_idx(--l) : SEQ_START_TOKEN;
 50}
 51
 52static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
 53{
 54        struct x25_route *rt;
 55
 56        ++*pos;
 57        if (v == SEQ_START_TOKEN) {
 58                rt = NULL;
 59                if (!list_empty(&x25_route_list))
 60                        rt = list_entry(x25_route_list.next,
 61                                        struct x25_route, node);
 62                goto out;
 63        }
 64        rt = v;
 65        if (rt->node.next != &x25_route_list)
 66                rt = list_entry(rt->node.next, struct x25_route, node);
 67        else
 68                rt = NULL;
 69out:
 70        return rt;
 71}
 72
 73static void x25_seq_route_stop(struct seq_file *seq, void *v)
 74        __releases(x25_route_list_lock)
 75{
 76        read_unlock_bh(&x25_route_list_lock);
 77}
 78
 79static int x25_seq_route_show(struct seq_file *seq, void *v)
 80{
 81        struct x25_route *rt;
 82
 83        if (v == SEQ_START_TOKEN) {
 84                seq_puts(seq, "Address          Digits  Device\n");
 85                goto out;
 86        }
 87
 88        rt = v;
 89        seq_printf(seq, "%-15s  %-6d  %-5s\n",
 90                   rt->address.x25_addr, rt->sigdigits,
 91                   rt->dev ? rt->dev->name : "???");
 92out:
 93        return 0;
 94}
 95
 96static __inline__ struct sock *x25_get_socket_idx(loff_t pos)
 97{
 98        struct sock *s;
 99        struct hlist_node *node;
100
101        sk_for_each(s, node, &x25_list)
102                if (!pos--)
103                        goto found;
104        s = NULL;
105found:
106        return s;
107}
108
109static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
110        __acquires(x25_list_lock)
111{
112        loff_t l = *pos;
113
114        read_lock_bh(&x25_list_lock);
115        return l ? x25_get_socket_idx(--l) : SEQ_START_TOKEN;
116}
117
118static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
119{
120        struct sock *s;
121
122        ++*pos;
123        if (v == SEQ_START_TOKEN) {
124                s = sk_head(&x25_list);
125                goto out;
126        }
127        s = sk_next(v);
128out:
129        return s;
130}
131
132static void x25_seq_socket_stop(struct seq_file *seq, void *v)
133        __releases(x25_list_lock)
134{
135        read_unlock_bh(&x25_list_lock);
136}
137
138static int x25_seq_socket_show(struct seq_file *seq, void *v)
139{
140        struct sock *s;
141        struct x25_sock *x25;
142        struct net_device *dev;
143        const char *devname;
144
145        if (v == SEQ_START_TOKEN) {
146                seq_printf(seq, "dest_addr  src_addr   dev   lci st vs vr "
147                                "va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
148                goto out;
149        }
150
151        s = v;
152        x25 = x25_sk(s);
153
154        if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
155                devname = "???";
156        else
157                devname = x25->neighbour->dev->name;
158
159        seq_printf(seq, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu "
160                        "%3lu %3lu %3lu %5d %5d %ld\n",
161                   !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
162                   !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
163                   devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
164                   x25->va, x25_display_timer(s) / HZ, x25->t2  / HZ,
165                   x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
166                   atomic_read(&s->sk_wmem_alloc),
167                   atomic_read(&s->sk_rmem_alloc),
168                   s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
169out:
170        return 0;
171}
172
173static __inline__ struct x25_forward *x25_get_forward_idx(loff_t pos)
174{
175        struct x25_forward *f;
176        struct list_head *entry;
177
178        list_for_each(entry, &x25_forward_list) {
179                f = list_entry(entry, struct x25_forward, node);
180                if (!pos--)
181                        goto found;
182        }
183
184        f = NULL;
185found:
186        return f;
187}
188
189static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
190        __acquires(x25_forward_list_lock)
191{
192        loff_t l = *pos;
193
194        read_lock_bh(&x25_forward_list_lock);
195        return l ? x25_get_forward_idx(--l) : SEQ_START_TOKEN;
196}
197
198static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos)
199{
200        struct x25_forward *f;
201
202        ++*pos;
203        if (v == SEQ_START_TOKEN) {
204                f = NULL;
205                if (!list_empty(&x25_forward_list))
206                        f = list_entry(x25_forward_list.next,
207                                        struct x25_forward, node);
208                goto out;
209        }
210        f = v;
211        if (f->node.next != &x25_forward_list)
212                f = list_entry(f->node.next, struct x25_forward, node);
213        else
214                f = NULL;
215out:
216        return f;
217
218}
219
220static void x25_seq_forward_stop(struct seq_file *seq, void *v)
221        __releases(x25_forward_list_lock)
222{
223        read_unlock_bh(&x25_forward_list_lock);
224}
225
226static int x25_seq_forward_show(struct seq_file *seq, void *v)
227{
228        struct x25_forward *f;
229
230        if (v == SEQ_START_TOKEN) {
231                seq_printf(seq, "lci dev1       dev2\n");
232                goto out;
233        }
234
235        f = v;
236
237        seq_printf(seq, "%d %-10s %-10s\n",
238                        f->lci, f->dev1->name, f->dev2->name);
239
240out:
241        return 0;
242}
243
244static const struct seq_operations x25_seq_route_ops = {
245        .start  = x25_seq_route_start,
246        .next   = x25_seq_route_next,
247        .stop   = x25_seq_route_stop,
248        .show   = x25_seq_route_show,
249};
250
251static const struct seq_operations x25_seq_socket_ops = {
252        .start  = x25_seq_socket_start,
253        .next   = x25_seq_socket_next,
254        .stop   = x25_seq_socket_stop,
255        .show   = x25_seq_socket_show,
256};
257
258static const struct seq_operations x25_seq_forward_ops = {
259        .start  = x25_seq_forward_start,
260        .next   = x25_seq_forward_next,
261        .stop   = x25_seq_forward_stop,
262        .show   = x25_seq_forward_show,
263};
264
265static int x25_seq_socket_open(struct inode *inode, struct file *file)
266{
267        return seq_open(file, &x25_seq_socket_ops);
268}
269
270static int x25_seq_route_open(struct inode *inode, struct file *file)
271{
272        return seq_open(file, &x25_seq_route_ops);
273}
274
275static int x25_seq_forward_open(struct inode *inode, struct file *file)
276{
277        return seq_open(file, &x25_seq_forward_ops);
278}
279
280static const struct file_operations x25_seq_socket_fops = {
281        .owner                = THIS_MODULE,
282        .open                = x25_seq_socket_open,
283        .read                = seq_read,
284        .llseek                = seq_lseek,
285        .release        = seq_release,
286};
287
288static const struct file_operations x25_seq_route_fops = {
289        .owner                = THIS_MODULE,
290        .open                = x25_seq_route_open,
291        .read                = seq_read,
292        .llseek                = seq_lseek,
293        .release        = seq_release,
294};
295
296static const struct file_operations x25_seq_forward_fops = {
297        .owner                = THIS_MODULE,
298        .open                = x25_seq_forward_open,
299        .read                = seq_read,
300        .llseek                = seq_lseek,
301        .release        = seq_release,
302};
303
304static struct proc_dir_entry *x25_proc_dir;
305
306int __init x25_proc_init(void)
307{
308        struct proc_dir_entry *p;
309        int rc = -ENOMEM;
310
311        x25_proc_dir = proc_mkdir("x25", init_net.proc_net);
312        if (!x25_proc_dir)
313                goto out;
314
315        p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops);
316        if (!p)
317                goto out_route;
318
319        p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops);
320        if (!p)
321                goto out_socket;
322
323        p = proc_create("forward", S_IRUGO, x25_proc_dir,
324                        &x25_seq_forward_fops);
325        if (!p)
326                goto out_forward;
327        rc = 0;
328
329out:
330        return rc;
331out_forward:
332        remove_proc_entry("socket", x25_proc_dir);
333out_socket:
334        remove_proc_entry("route", x25_proc_dir);
335out_route:
336        remove_proc_entry("x25", init_net.proc_net);
337        goto out;
338}
339
340void __exit x25_proc_exit(void)
341{
342        remove_proc_entry("forward", x25_proc_dir);
343        remove_proc_entry("route", x25_proc_dir);
344        remove_proc_entry("socket", x25_proc_dir);
345        remove_proc_entry("x25", init_net.proc_net);
346}
347
348#else /* CONFIG_PROC_FS */
349
350int __init x25_proc_init(void)
351{
352        return 0;
353}
354
355void __exit x25_proc_exit(void)
356{
357}
358#endif /* CONFIG_PROC_FS */