Showing error 1551

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


Source:

  1/*****************************************************************************
  2* wanproc.c        WAN Router Module. /proc filesystem interface.
  3*
  4*                This module is completely hardware-independent and provides
  5*                access to the router using Linux /proc filesystem.
  6*
  7* Author:         Gideon Hack
  8*
  9* Copyright:        (c) 1995-1999 Sangoma Technologies Inc.
 10*
 11*                This program 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* Jun 02, 1999  Gideon Hack        Updates for Linux 2.2.X kernels.
 17* Jun 29, 1997        Alan Cox        Merged with 1.0.3 vendor code
 18* Jan 29, 1997        Gene Kozin        v1.0.1. Implemented /proc read routines
 19* Jan 30, 1997        Alan Cox        Hacked around for 2.1
 20* Dec 13, 1996        Gene Kozin        Initial version (based on Sangoma's WANPIPE)
 21*****************************************************************************/
 22
 23#include <linux/init.h>                /* __initfunc et al. */
 24#include <linux/stddef.h>        /* offsetof(), etc. */
 25#include <linux/errno.h>        /* return codes */
 26#include <linux/kernel.h>
 27#include <linux/module.h>
 28#include <linux/wanrouter.h>        /* WAN router API definitions */
 29#include <linux/seq_file.h>
 30#include <linux/smp_lock.h>
 31
 32#include <net/net_namespace.h>
 33#include <asm/io.h>
 34
 35#define PROC_STATS_FORMAT "%30s: %12lu\n"
 36
 37/****** Defines and Macros **************************************************/
 38
 39#define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
 40                              (prot == WANCONFIG_X25) ? " X25" : \
 41                                 (prot == WANCONFIG_PPP) ? " PPP" : \
 42                                    (prot == WANCONFIG_CHDLC) ? " CHDLC": \
 43                                       (prot == WANCONFIG_MPPP) ? " MPPP" : \
 44                                           " Unknown" )
 45
 46/****** Function Prototypes *************************************************/
 47
 48#ifdef CONFIG_PROC_FS
 49
 50/* Miscellaneous */
 51
 52/*
 53 *        Structures for interfacing with the /proc filesystem.
 54 *        Router creates its own directory /proc/net/router with the folowing
 55 *        entries:
 56 *        config                device configuration
 57 *        status                global device statistics
 58 *        <device>        entry for each WAN device
 59 */
 60
 61/*
 62 *        Generic /proc/net/router/<file> file and inode operations
 63 */
 64
 65/*
 66 *        /proc/net/router
 67 */
 68
 69static struct proc_dir_entry *proc_router;
 70
 71/* Strings */
 72
 73/*
 74 *        Interface functions
 75 */
 76
 77/****** Proc filesystem entry points ****************************************/
 78
 79/*
 80 *        Iterator
 81 */
 82static void *r_start(struct seq_file *m, loff_t *pos)
 83{
 84        struct wan_device *wandev;
 85        loff_t l = *pos;
 86
 87        lock_kernel();
 88        if (!l--)
 89                return SEQ_START_TOKEN;
 90        for (wandev = wanrouter_router_devlist; l-- && wandev;
 91             wandev = wandev->next)
 92                ;
 93        return wandev;
 94}
 95
 96static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 97{
 98        struct wan_device *wandev = v;
 99        (*pos)++;
100        return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
101}
102
103static void r_stop(struct seq_file *m, void *v)
104{
105        unlock_kernel();
106}
107
108static int config_show(struct seq_file *m, void *v)
109{
110        struct wan_device *p = v;
111        if (v == SEQ_START_TOKEN) {
112                seq_puts(m, "Device name    | port |IRQ|DMA|  mem.addr  |"
113                            "mem.size|option1|option2|option3|option4\n");
114                return 0;
115        }
116        if (!p->state)
117                return 0;
118        seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
119                        p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize,
120                        p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]);
121        return 0;
122}
123
124static int status_show(struct seq_file *m, void *v)
125{
126        struct wan_device *p = v;
127        if (v == SEQ_START_TOKEN) {
128                seq_puts(m, "Device name    |protocol|station|interface|"
129                            "clocking|baud rate| MTU |ndev|link state\n");
130                return 0;
131        }
132        if (!p->state)
133                return 0;
134        seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |",
135                p->name,
136                PROT_DECODE(p->config_id),
137                p->config_id == WANCONFIG_FR ?
138                        (p->station ? "Node" : "CPE") :
139                        (p->config_id == WANCONFIG_X25 ?
140                        (p->station ? "DCE" : "DTE") :
141                        ("N/A")),
142                p->interface ? "V.35" : "RS-232",
143                p->clocking ? "internal" : "external",
144                p->bps,
145                p->mtu,
146                p->ndev);
147
148        switch (p->state) {
149        case WAN_UNCONFIGURED:
150                seq_printf(m, "%-12s\n", "unconfigured");
151                break;
152        case WAN_DISCONNECTED:
153                seq_printf(m, "%-12s\n", "disconnected");
154                break;
155        case WAN_CONNECTING:
156                seq_printf(m, "%-12s\n", "connecting");
157                break;
158        case WAN_CONNECTED:
159                seq_printf(m, "%-12s\n", "connected");
160                break;
161        default:
162                seq_printf(m, "%-12s\n", "invalid");
163                break;
164        }
165        return 0;
166}
167
168static const struct seq_operations config_op = {
169        .start        = r_start,
170        .next        = r_next,
171        .stop        = r_stop,
172        .show        = config_show,
173};
174
175static const struct seq_operations status_op = {
176        .start        = r_start,
177        .next        = r_next,
178        .stop        = r_stop,
179        .show        = status_show,
180};
181
182static int config_open(struct inode *inode, struct file *file)
183{
184        return seq_open(file, &config_op);
185}
186
187static int status_open(struct inode *inode, struct file *file)
188{
189        return seq_open(file, &status_op);
190}
191
192static const struct file_operations config_fops = {
193        .owner         = THIS_MODULE,
194        .open         = config_open,
195        .read         = seq_read,
196        .llseek         = seq_lseek,
197        .release = seq_release,
198};
199
200static const struct file_operations status_fops = {
201        .owner         = THIS_MODULE,
202        .open         = status_open,
203        .read         = seq_read,
204        .llseek         = seq_lseek,
205        .release = seq_release,
206};
207
208static int wandev_show(struct seq_file *m, void *v)
209{
210        struct wan_device *wandev = m->private;
211
212        if (wandev->magic != ROUTER_MAGIC)
213                return 0;
214
215        if (!wandev->state) {
216                seq_puts(m, "device is not configured!\n");
217                return 0;
218        }
219
220        /* Update device statistics */
221        if (wandev->update) {
222                int err = wandev->update(wandev);
223                if (err == -EAGAIN) {
224                        seq_puts(m, "Device is busy!\n");
225                        return 0;
226                }
227                if (err) {
228                        seq_puts(m, "Device is not configured!\n");
229                        return 0;
230                }
231        }
232
233        seq_printf(m, PROC_STATS_FORMAT,
234                "total packets received", wandev->stats.rx_packets);
235        seq_printf(m, PROC_STATS_FORMAT,
236                "total packets transmitted", wandev->stats.tx_packets);
237        seq_printf(m, PROC_STATS_FORMAT,
238                "total bytes received", wandev->stats.rx_bytes);
239        seq_printf(m, PROC_STATS_FORMAT,
240                "total bytes transmitted", wandev->stats.tx_bytes);
241        seq_printf(m, PROC_STATS_FORMAT,
242                "bad packets received", wandev->stats.rx_errors);
243        seq_printf(m, PROC_STATS_FORMAT,
244                "packet transmit problems", wandev->stats.tx_errors);
245        seq_printf(m, PROC_STATS_FORMAT,
246                "received frames dropped", wandev->stats.rx_dropped);
247        seq_printf(m, PROC_STATS_FORMAT,
248                "transmit frames dropped", wandev->stats.tx_dropped);
249        seq_printf(m, PROC_STATS_FORMAT,
250                "multicast packets received", wandev->stats.multicast);
251        seq_printf(m, PROC_STATS_FORMAT,
252                "transmit collisions", wandev->stats.collisions);
253        seq_printf(m, PROC_STATS_FORMAT,
254                "receive length errors", wandev->stats.rx_length_errors);
255        seq_printf(m, PROC_STATS_FORMAT,
256                "receiver overrun errors", wandev->stats.rx_over_errors);
257        seq_printf(m, PROC_STATS_FORMAT,
258                "CRC errors", wandev->stats.rx_crc_errors);
259        seq_printf(m, PROC_STATS_FORMAT,
260                "frame format errors (aborts)", wandev->stats.rx_frame_errors);
261        seq_printf(m, PROC_STATS_FORMAT,
262                "receiver fifo overrun", wandev->stats.rx_fifo_errors);
263        seq_printf(m, PROC_STATS_FORMAT,
264                "receiver missed packet", wandev->stats.rx_missed_errors);
265        seq_printf(m, PROC_STATS_FORMAT,
266                "aborted frames transmitted", wandev->stats.tx_aborted_errors);
267        return 0;
268}
269
270static int wandev_open(struct inode *inode, struct file *file)
271{
272        return single_open(file, wandev_show, PDE(inode)->data);
273}
274
275static const struct file_operations wandev_fops = {
276        .owner         = THIS_MODULE,
277        .open         = wandev_open,
278        .read         = seq_read,
279        .llseek         = seq_lseek,
280        .release = single_release,
281        .unlocked_ioctl  = wanrouter_ioctl,
282};
283
284/*
285 *        Initialize router proc interface.
286 */
287
288int __init wanrouter_proc_init(void)
289{
290        struct proc_dir_entry *p;
291        proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
292        if (!proc_router)
293                goto fail;
294
295        p = proc_create("config", S_IRUGO, proc_router, &config_fops);
296        if (!p)
297                goto fail_config;
298        p = proc_create("status", S_IRUGO, proc_router, &status_fops);
299        if (!p)
300                goto fail_stat;
301        return 0;
302fail_stat:
303        remove_proc_entry("config", proc_router);
304fail_config:
305        remove_proc_entry(ROUTER_NAME, init_net.proc_net);
306fail:
307        return -ENOMEM;
308}
309
310/*
311 *        Clean up router proc interface.
312 */
313
314void wanrouter_proc_cleanup(void)
315{
316        remove_proc_entry("config", proc_router);
317        remove_proc_entry("status", proc_router);
318        remove_proc_entry(ROUTER_NAME, init_net.proc_net);
319}
320
321/*
322 *        Add directory entry for WAN device.
323 */
324
325int wanrouter_proc_add(struct wan_device* wandev)
326{
327        if (wandev->magic != ROUTER_MAGIC)
328                return -EINVAL;
329
330        wandev->dent = proc_create(wandev->name, S_IRUGO,
331                                   proc_router, &wandev_fops);
332        if (!wandev->dent)
333                return -ENOMEM;
334        wandev->dent->data        = wandev;
335        return 0;
336}
337
338/*
339 *        Delete directory entry for WAN device.
340 */
341int wanrouter_proc_delete(struct wan_device* wandev)
342{
343        if (wandev->magic != ROUTER_MAGIC)
344                return -EINVAL;
345        remove_proc_entry(wandev->name, proc_router);
346        return 0;
347}
348
349#else
350
351/*
352 *        No /proc - output stubs
353 */
354
355int __init wanrouter_proc_init(void)
356{
357        return 0;
358}
359
360void wanrouter_proc_cleanup(void)
361{
362}
363
364int wanrouter_proc_add(struct wan_device *wandev)
365{
366        return 0;
367}
368
369int wanrouter_proc_delete(struct wan_device *wandev)
370{
371        return 0;
372}
373
374#endif
375
376/*
377 *        End
378 */
379