[PATCH] af_netrom.c: do resource release on failure

From: Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Date: Fri Sep 08 2000 - 13:15:59 EDT

  • Next message: Linus Torvalds: "Re: [PATCH] panic when booting Intel XXPRESS SMP boards"

    Hi,

            Please take a look and consider applying. Some of it are small cleanups, if
    they're deemed unnecessary, lemme now and I'm back it off. I think that there
    are some more unchecked calls that need fixing, but I think its better to keep
    the patches smaller and incremental, what do you think?

                            - Arnaldo

    --- linux-2.4.0-test8-6/include/net/nrcall.h Fri Apr 12 03:49:47 1996
    +++ linux-2.4.0-test8-6.acme/include/net/nrcall.h Fri Sep 8 14:05:19 2000
    @@ -1,2 +1,2 @@
     /* Separate to keep compilation of protocols.c simpler */
    -extern void nr_proto_init(struct net_proto *pro);
    +extern int nr_proto_init(struct net_proto *pro);
    --- linux-2.4.0-test8-6/net/netrom/af_netrom.c Thu Sep 7 14:01:43 2000
    +++ linux-2.4.0-test8-6.acme/net/netrom/af_netrom.c Fri Sep 8 14:03:49 2000
    @@ -31,6 +31,8 @@
      * NET/ROM 007 Jonathan(G4KLX) New timer architecture.
      * Impmented Idle timer.
      * Arnaldo C. Melo s/suser/capable/, micro cleanups
    + * Arnaldo C. Melo further cleanups, do resource release on
    + * failure in nr_proto_init
      */
     
     #include <linux/config.h>
    @@ -68,6 +70,9 @@
     
     int nr_ndevs = 4;
     
    +static const char __initdata *version_info =
    + "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.1\n";
    +
     int sysctl_netrom_default_path_quality = NR_DEFAULT_QUAL;
     int sysctl_netrom_obsolescence_count_initialiser = NR_DEFAULT_OBS;
     int sysctl_netrom_network_ttl_initialiser = NR_DEFAULT_TTL;
    @@ -128,20 +133,18 @@
     
             if ((s = nr_list) == sk) {
                     nr_list = s->next;
    - restore_flags(flags);
    - return;
    + goto out;
             }
     
             while (s != NULL && s->next != NULL) {
                     if (s->next == sk) {
                             s->next = sk->next;
    - restore_flags(flags);
    - return;
    + goto out;
                     }
     
                     s = s->next;
             }
    -
    +out:
             restore_flags(flags);
     }
     
    @@ -201,15 +204,12 @@
             save_flags(flags);
             cli();
     
    - for (s = nr_list; s != NULL; s = s->next) {
    - if (ax25cmp(&s->protinfo.nr->source_addr, addr) == 0 && s->state == TCP_LISTEN) {
    - restore_flags(flags);
    - return s;
    - }
    - }
    + for (s = nr_list; s != NULL; s = s->next)
    + if (ax25cmp(&s->protinfo.nr->source_addr, addr) == 0 && s->state == TCP_LISTEN)
    + break;
     
             restore_flags(flags);
    - return NULL;
    + return s;
     }
     
     /*
    @@ -223,16 +223,12 @@
             save_flags(flags);
             cli();
     
    - for (s = nr_list; s != NULL; s = s->next) {
    - if (s->protinfo.nr->my_index == index && s->protinfo.nr->my_id == id) {
    - restore_flags(flags);
    - return s;
    - }
    - }
    + for (s = nr_list; s != NULL; s = s->next)
    + if (s->protinfo.nr->my_index == index && s->protinfo.nr->my_id == id)
    + break;
     
             restore_flags(flags);
    -
    - return NULL;
    + return s;
     }
     
     /*
    @@ -246,16 +242,14 @@
             save_flags(flags);
             cli();
     
    - for (s = nr_list; s != NULL; s = s->next) {
    - if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id && ax25cmp(&s->protinfo.nr->dest_addr, dest) == 0) {
    - restore_flags(flags);
    - return s;
    - }
    - }
    + for (s = nr_list; s != NULL; s = s->next)
    + if (s->protinfo.nr->your_index == index &&
    + s->protinfo.nr->your_id == id &&
    + ax25cmp(&s->protinfo.nr->dest_addr, dest) == 0)
    + break;
     
             restore_flags(flags);
    -
    - return NULL;
    + return s;
     }
     
     /*
    @@ -389,10 +383,9 @@
                                     return -EINVAL;
                             sk->protinfo.nr->idle = opt * 60 * HZ;
                             return 0;
    -
    - default:
    - return -ENOPROTOOPT;
             }
    +
    + return -ENOPROTOOPT;
     }
     
     static int nr_getsockopt(struct socket *sock, int level, int optname,
    @@ -1122,12 +1115,11 @@
                     }
     
                     case SIOCGSTAMP:
    - if (sk != NULL) {
    - if (sk->stamp.tv_sec == 0)
    - return -ENOENT;
    - return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
    - }
    - return -EINVAL;
    + if (!sk)
    + return -EINVAL;
    + if (sk->stamp.tv_sec == 0)
    + return -ENOENT;
    + return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
     
                     case SIOCGIFADDR:
                     case SIOCSIFADDR:
    @@ -1146,13 +1138,9 @@
                     case SIOCNRDECOBS:
                             if (!capable(CAP_NET_ADMIN)) return -EPERM;
                             return nr_rt_ioctl(cmd, (void *)arg);
    -
    - default:
    - return dev_ioctl(cmd, (void *)arg);
             }
     
    - /*NOTREACHED*/
    - return 0;
    + return dev_ioctl(cmd, (void *)arg);
     }
     
     static int nr_get_info(char *buffer, char **start, off_t offset, int length)
    @@ -1261,13 +1249,13 @@
     
     static struct net_device *dev_nr;
     
    -void __init nr_proto_init(struct net_proto *pro)
    +int __init nr_proto_init(struct net_proto *pro)
     {
    - int i;
    + int i, err = -ENOMEM;
     
             if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) {
                     printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
    - return;
    + return -ENOMEM;
             }
     
             memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device));
    @@ -1275,12 +1263,14 @@
             for (i = 0; i < nr_ndevs; i++) {
                     sprintf(dev_nr[i].name, "nr%d", i);
                     dev_nr[i].init = nr_init;
    - register_netdev(&dev_nr[i]);
    + err = register_netdev(&dev_nr[i]);
    + if (err)
    + goto cleanup_dev_nr;
             }
     
             sock_register(&nr_family_ops);
             register_netdevice_notifier(&nr_dev_notifier);
    - printk(KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.1\n");
    + printk(version_info);
     
             ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
             ax25_linkfail_register(nr_link_failed);
    @@ -1292,10 +1282,27 @@
             nr_loopback_init();
     
     #ifdef CONFIG_PROC_FS
    - proc_net_create("nr", 0, nr_get_info);
    - proc_net_create("nr_neigh", 0, nr_neigh_get_info);
    - proc_net_create("nr_nodes", 0, nr_nodes_get_info);
    + if (!proc_net_create("nr", 0, nr_get_info))
    + goto cleanup_dev_nr;
    + if (!proc_net_create("nr_neigh", 0, nr_neigh_get_info))
    + goto cleanup_nr;
    + if (!proc_net_create("nr_nodes", 0, nr_nodes_get_info))
    + goto cleanup_nr_neigh;
    +#endif
    + return 0;
    +#ifdef CONFIG_PROC_FS
    +cleanup_nr_neigh:
    + proc_net_remove("nr_neigh");
    +cleanup_nr:
    + proc_net_remove("nr");
     #endif
    +cleanup_dev_nr:
    + while (--i >= 0) {
    + dev_nr[i].init = NULL;
    + unregister_netdev(&dev_nr[i]);
    + }
    + kfree(dev_nr);
    + return err;
     }
     
     #ifdef MODULE
    @@ -1309,9 +1316,7 @@
     
     int init_module(void)
     {
    - nr_proto_init(NULL);
    -
    - return 0;
    + return nr_proto_init(NULL);
     }
     
     void cleanup_module(void)
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Fri Sep 08 2000 - 13:18:24 EDT