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

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


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 15 2000 - 21:00:10 EST