[PATCH] comx.c resource allocation and other fixes

From: Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Date: Sat Aug 12 2000 - 13:28:56 EST


Hi,

         Please take a look and consider applying. Please note that the use of
forward gotos to do cleanups is considered to be a general kernel coding
convention.

- Arnaldo

--- linux-2.4.0-test7-pre2/drivers/net/wan/comx.c Wed Jun 21 14:10:02 2000
+++ linux-2.4.0-test7-pre2.acme/drivers/net/wan/comx.c Sat Aug 12 15:00:29 2000
@@ -8,6 +8,9 @@
  * Previous maintainer: Tivadar Szemethy <tiv@itc.hu>
  * Current maintainer: Gergely Madarasz <gorgo@itc.hu>
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.85)
+ *
  * Copyright (C) 1995-1999 ITConsult-Pro Co.
  *
  * This program is free software; you can redistribute it and/or
@@ -39,9 +42,14 @@
  * Version 0.84 (99/12/01):
  * - comx_status should not check for IFF_UP (to report
  * line status from dev->open())
+ * Version 0.85 (2000/08/11):
+ * - reorganize comx_mkdir and comx_init to release previously
+ * allocated resources when one resource allocation fail
+ * - minor similar fix in comx_init_dev
+ * - proc entries for drivers in 2.4 have to be in /proc/driver
  */
 
-#define VERSION "0.84"
+#define VERSION "0.85"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -506,6 +514,7 @@
         ch->loadavg_size = ch->loadavg[2] / ch->loadavg[0] + 1;
         if ((ch->avg_bytes = kmalloc(ch->loadavg_size *
                 sizeof(unsigned long) * 2, GFP_KERNEL)) == NULL) {
+ kfree(ch);
                 return -ENOMEM;
         }
 
@@ -762,11 +771,13 @@
         struct proc_dir_entry *new_dir, *debug_file;
         struct net_device *dev;
         struct comx_channel *ch;
+ int ret = -ENOMEM;
+
+ new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR,
+ comx_root_dir);
 
- if ((new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR,
- comx_root_dir)) == NULL) {
+ if (!new_dir)
                 return -EIO;
- }
 
         new_dir->nlink = 2;
         new_dir->data = NULL; // ide jon majd a struct dev
@@ -774,58 +785,71 @@
         /* Ezek kellenek */
         if (!create_comx_proc_entry(FILENAME_HARDWARE, 0644,
             strlen(HWNAME_NONE) + 1, new_dir)) {
- return -ENOMEM;
+ goto cleanup_new_dir;
         }
         if (!create_comx_proc_entry(FILENAME_PROTOCOL, 0644,
             strlen(PROTONAME_NONE) + 1, new_dir)) {
- return -ENOMEM;
+ goto cleanup_hardware;
         }
         if (!create_comx_proc_entry(FILENAME_STATUS, 0444, 0, new_dir)) {
- return -ENOMEM;
+ goto cleanup_protocol;
         }
         if (!create_comx_proc_entry(FILENAME_LINEUPDELAY, 0644, 2, new_dir)) {
- return -ENOMEM;
+ goto cleanup_status;
         }
 
- if ((debug_file = create_proc_entry(FILENAME_DEBUG,
- S_IFREG | 0644, new_dir)) == NULL) {
- return -ENOMEM;
- }
+ debug_file = create_proc_entry(FILENAME_DEBUG, S_IFREG | 0644, new_dir);
+ if (!debug_file)
+ goto cleanup_lineupdelay;
+
         debug_file->data = (void *)debug_file;
         debug_file->read_proc = NULL; // see below
         debug_file->write_proc = &comx_write_proc;
         debug_file->nlink = 1;
 
- if ((dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) {
- return -ENOMEM;
- }
+ dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+ if (!dev)
+ goto cleanup_debug;
+
         memset(dev, 0, sizeof(struct net_device));
         strcpy(dev->name, (char *)new_dir->name);
         dev->init = comx_init_dev;
 
         if (register_netdevice(dev)) {
- return -EIO;
+ ret = -EIO;
+ goto cleanup_dev;
         }
+
         ch=dev->priv;
- if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device),
- GFP_KERNEL)) == NULL) {
- return -ENOMEM;
- }
+ ch->if_ptr = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
+ if(!ch->if_ptr)
+ goto cleanup_register;
+
         memset(ch->if_ptr, 0, sizeof(struct ppp_device));
         ch->debug_file = debug_file;
         ch->procdir = new_dir;
         new_dir->data = dev;
 
         ch->debug_start = ch->debug_end = 0;
- if ((ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE,
- GFP_KERNEL)) == NULL) {
- return -ENOMEM;
- }
+ ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE, GFP_KERNEL);
+
+ if (!ch->debug_area)
+ goto cleanup_if_ptr;
 
         ch->lineup_delay = DEFAULT_LINEUP_DELAY;
 
         MOD_INC_USE_COUNT;
         return 0;
+cleanup_if_ptr: kfree(ch->if_ptr);
+cleanup_register: unregister_netdevice(dev);
+cleanup_dev: kfree(dev);
+cleanup_debug: remove_proc_entry(FILENAME_DEBUG, new_dir);
+cleanup_lineupdelay: remove_proc_entry(FILENAME_LINEUPDELAY, new_dir);
+cleanup_status: remove_proc_entry(FILENAME_STATUS, new_dir);
+cleanup_protocol: remove_proc_entry(FILENAME_PROTOCOL, new_dir);
+cleanup_hardware: remove_proc_entry(FILENAME_HARDWARE, new_dir);
+cleanup_new_dir: remove_proc_entry(dentry->d_name.name, NULL);
+ return ret;
 }
 
 static int comx_rmdir(struct inode *dir, struct dentry *dentry)
@@ -1030,7 +1054,7 @@
 {
         struct proc_dir_entry *new_file;
 
- comx_root_dir = create_proc_entry("comx",
+ comx_root_dir = create_proc_entry(COMX_ROOT_DIR_NAME,
                 S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, &proc_root);
         if (!comx_root_dir)
                 return -ENOMEM;
@@ -1038,7 +1062,7 @@
 
         if ((new_file = create_proc_entry(FILENAME_HARDWARELIST,
            S_IFREG | 0444, comx_root_dir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_root_dir;
         }
         
         new_file->data = new_file;
@@ -1048,7 +1072,7 @@
 
         if ((new_file = create_proc_entry(FILENAME_PROTOCOLLIST,
            S_IFREG | 0444, comx_root_dir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_hardwarelist;
         }
         
         new_file->data = new_file;
@@ -1082,9 +1106,10 @@
 #ifdef CONFIG_COMX_PROTO_FR
         comx_proto_fr_init();
 #endif
-#endif
-
         return 0;
+cleanup_hardwarelist: remove_proc_entry(FILENAME_HARDWARELIST, comx_root_dir);
+cleanup_rootdir: remove_proc_entry(COMX_ROOT_DIR_NAME, &proc_root);
+ return -ENOMEM;
 }
 
 #ifdef MODULE
--- linux-2.4.0-test7-pre2/drivers/net/wan/comx.h Wed Apr 12 13:38:57 2000
+++ linux-2.4.0-test7-pre2.acme/drivers/net/wan/comx.h Sat Aug 12 15:00:29 2000
@@ -6,6 +6,11 @@
  * Previous maintainer: Tivadar Szemethy <tiv@itc.hu>
  * Currently maintained by: Gergely Madarasz <gorgo@itc.hu>
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - proc entries for drivers should be under /proc/driver
+ * in 2.4
+ *
  * Copyright (C) 1995-1999 ITConsult-Pro Co. <info@itc.hu>
  *
  * This program is free software; you can redistribute it and/or
@@ -125,7 +130,7 @@
         int value;
         };
 
-#define COMX_ROOT_DIR_NAME "comx"
+#define COMX_ROOT_DIR_NAME "driver/comx"
 
 #define FILENAME_HARDWARE "boardtype"
 #define FILENAME_HARDWARELIST "boardtypes"

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Aug 15 2000 - 21:00:28 EST