Showing error 1457

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/appletalk/atalk_proc.c
Line in file: 35
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

  1/*
  2 *         atalk_proc.c - proc support for Appletalk
  3 *
  4 *         Copyright(c) Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  5 *
  6 *        This program is free software; you can redistribute it and/or modify it
  7 *        under the terms of the GNU General Public License as published by the
  8 *        Free Software Foundation, version 2.
  9 */
 10
 11#include <linux/init.h>
 12#include <linux/proc_fs.h>
 13#include <linux/seq_file.h>
 14#include <net/net_namespace.h>
 15#include <net/sock.h>
 16#include <linux/atalk.h>
 17
 18
 19static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
 20{
 21        struct atalk_iface *i;
 22
 23        for (i = atalk_interfaces; pos && i; i = i->next)
 24                --pos;
 25
 26        return i;
 27}
 28
 29static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos)
 30        __acquires(atalk_interfaces_lock)
 31{
 32        loff_t l = *pos;
 33
 34        read_lock_bh(&atalk_interfaces_lock);
 35        return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN;
 36}
 37
 38static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
 39{
 40        struct atalk_iface *i;
 41
 42        ++*pos;
 43        if (v == SEQ_START_TOKEN) {
 44                i = NULL;
 45                if (atalk_interfaces)
 46                        i = atalk_interfaces;
 47                goto out;
 48        }
 49        i = v;
 50        i = i->next;
 51out:
 52        return i;
 53}
 54
 55static void atalk_seq_interface_stop(struct seq_file *seq, void *v)
 56        __releases(atalk_interfaces_lock)
 57{
 58        read_unlock_bh(&atalk_interfaces_lock);
 59}
 60
 61static int atalk_seq_interface_show(struct seq_file *seq, void *v)
 62{
 63        struct atalk_iface *iface;
 64
 65        if (v == SEQ_START_TOKEN) {
 66                seq_puts(seq, "Interface        Address   Networks  "
 67                              "Status\n");
 68                goto out;
 69        }
 70
 71        iface = v;
 72        seq_printf(seq, "%-16s %04X:%02X  %04X-%04X  %d\n",
 73                   iface->dev->name, ntohs(iface->address.s_net),
 74                   iface->address.s_node, ntohs(iface->nets.nr_firstnet),
 75                   ntohs(iface->nets.nr_lastnet), iface->status);
 76out:
 77        return 0;
 78}
 79
 80static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos)
 81{
 82        struct atalk_route *r;
 83
 84        for (r = atalk_routes; pos && r; r = r->next)
 85                --pos;
 86
 87        return r;
 88}
 89
 90static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos)
 91        __acquires(atalk_routes_lock)
 92{
 93        loff_t l = *pos;
 94
 95        read_lock_bh(&atalk_routes_lock);
 96        return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN;
 97}
 98
 99static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
100{
101        struct atalk_route *r;
102
103        ++*pos;
104        if (v == SEQ_START_TOKEN) {
105                r = NULL;
106                if (atalk_routes)
107                        r = atalk_routes;
108                goto out;
109        }
110        r = v;
111        r = r->next;
112out:
113        return r;
114}
115
116static void atalk_seq_route_stop(struct seq_file *seq, void *v)
117        __releases(atalk_routes_lock)
118{
119        read_unlock_bh(&atalk_routes_lock);
120}
121
122static int atalk_seq_route_show(struct seq_file *seq, void *v)
123{
124        struct atalk_route *rt;
125
126        if (v == SEQ_START_TOKEN) {
127                seq_puts(seq, "Target        Router  Flags Dev\n");
128                goto out;
129        }
130
131        if (atrtr_default.dev) {
132                rt = &atrtr_default;
133                seq_printf(seq, "Default     %04X:%02X  %-4d  %s\n",
134                               ntohs(rt->gateway.s_net), rt->gateway.s_node,
135                               rt->flags, rt->dev->name);
136        }
137
138        rt = v;
139        seq_printf(seq, "%04X:%02X     %04X:%02X  %-4d  %s\n",
140                   ntohs(rt->target.s_net), rt->target.s_node,
141                   ntohs(rt->gateway.s_net), rt->gateway.s_node,
142                   rt->flags, rt->dev->name);
143out:
144        return 0;
145}
146
147static __inline__ struct sock *atalk_get_socket_idx(loff_t pos)
148{
149        struct sock *s;
150        struct hlist_node *node;
151
152        sk_for_each(s, node, &atalk_sockets)
153                if (!pos--)
154                        goto found;
155        s = NULL;
156found:
157        return s;
158}
159
160static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos)
161        __acquires(atalk_sockets_lock)
162{
163        loff_t l = *pos;
164
165        read_lock_bh(&atalk_sockets_lock);
166        return l ? atalk_get_socket_idx(--l) : SEQ_START_TOKEN;
167}
168
169static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
170{
171        struct sock *i;
172
173        ++*pos;
174        if (v == SEQ_START_TOKEN) {
175                i = sk_head(&atalk_sockets);
176                goto out;
177        }
178        i = sk_next(v);
179out:
180        return i;
181}
182
183static void atalk_seq_socket_stop(struct seq_file *seq, void *v)
184        __releases(atalk_sockets_lock)
185{
186        read_unlock_bh(&atalk_sockets_lock);
187}
188
189static int atalk_seq_socket_show(struct seq_file *seq, void *v)
190{
191        struct sock *s;
192        struct atalk_sock *at;
193
194        if (v == SEQ_START_TOKEN) {
195                seq_printf(seq, "Type Local_addr  Remote_addr Tx_queue "
196                                "Rx_queue St UID\n");
197                goto out;
198        }
199
200        s = v;
201        at = at_sk(s);
202
203        seq_printf(seq, "%02X   %04X:%02X:%02X  %04X:%02X:%02X  %08X:%08X "
204                        "%02X %d\n",
205                   s->sk_type, ntohs(at->src_net), at->src_node, at->src_port,
206                   ntohs(at->dest_net), at->dest_node, at->dest_port,
207                   atomic_read(&s->sk_wmem_alloc),
208                   atomic_read(&s->sk_rmem_alloc),
209                   s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
210out:
211        return 0;
212}
213
214static const struct seq_operations atalk_seq_interface_ops = {
215        .start  = atalk_seq_interface_start,
216        .next   = atalk_seq_interface_next,
217        .stop   = atalk_seq_interface_stop,
218        .show   = atalk_seq_interface_show,
219};
220
221static const struct seq_operations atalk_seq_route_ops = {
222        .start  = atalk_seq_route_start,
223        .next   = atalk_seq_route_next,
224        .stop   = atalk_seq_route_stop,
225        .show   = atalk_seq_route_show,
226};
227
228static const struct seq_operations atalk_seq_socket_ops = {
229        .start  = atalk_seq_socket_start,
230        .next   = atalk_seq_socket_next,
231        .stop   = atalk_seq_socket_stop,
232        .show   = atalk_seq_socket_show,
233};
234
235static int atalk_seq_interface_open(struct inode *inode, struct file *file)
236{
237        return seq_open(file, &atalk_seq_interface_ops);
238}
239
240static int atalk_seq_route_open(struct inode *inode, struct file *file)
241{
242        return seq_open(file, &atalk_seq_route_ops);
243}
244
245static int atalk_seq_socket_open(struct inode *inode, struct file *file)
246{
247        return seq_open(file, &atalk_seq_socket_ops);
248}
249
250static const struct file_operations atalk_seq_interface_fops = {
251        .owner                = THIS_MODULE,
252        .open                = atalk_seq_interface_open,
253        .read                = seq_read,
254        .llseek                = seq_lseek,
255        .release        = seq_release,
256};
257
258static const struct file_operations atalk_seq_route_fops = {
259        .owner                = THIS_MODULE,
260        .open                = atalk_seq_route_open,
261        .read                = seq_read,
262        .llseek                = seq_lseek,
263        .release        = seq_release,
264};
265
266static const struct file_operations atalk_seq_socket_fops = {
267        .owner                = THIS_MODULE,
268        .open                = atalk_seq_socket_open,
269        .read                = seq_read,
270        .llseek                = seq_lseek,
271        .release        = seq_release,
272};
273
274static struct proc_dir_entry *atalk_proc_dir;
275
276int __init atalk_proc_init(void)
277{
278        struct proc_dir_entry *p;
279        int rc = -ENOMEM;
280
281        atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net);
282        if (!atalk_proc_dir)
283                goto out;
284        atalk_proc_dir->owner = THIS_MODULE;
285
286        p = proc_create("interface", S_IRUGO, atalk_proc_dir,
287                        &atalk_seq_interface_fops);
288        if (!p)
289                goto out_interface;
290
291        p = proc_create("route", S_IRUGO, atalk_proc_dir,
292                        &atalk_seq_route_fops);
293        if (!p)
294                goto out_route;
295
296        p = proc_create("socket", S_IRUGO, atalk_proc_dir,
297                        &atalk_seq_socket_fops);
298        if (!p)
299                goto out_socket;
300
301        p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops);
302        if (!p)
303                goto out_arp;
304
305        rc = 0;
306out:
307        return rc;
308out_arp:
309        remove_proc_entry("socket", atalk_proc_dir);
310out_socket:
311        remove_proc_entry("route", atalk_proc_dir);
312out_route:
313        remove_proc_entry("interface", atalk_proc_dir);
314out_interface:
315        remove_proc_entry("atalk", init_net.proc_net);
316        goto out;
317}
318
319void __exit atalk_proc_exit(void)
320{
321        remove_proc_entry("interface", atalk_proc_dir);
322        remove_proc_entry("route", atalk_proc_dir);
323        remove_proc_entry("socket", atalk_proc_dir);
324        remove_proc_entry("arp", atalk_proc_dir);
325        remove_proc_entry("atalk", init_net.proc_net);
326}