[PATCH] comx.c resource allocation and other fixes

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

  • Next message: Gerhard Mack: "Re: OT:ftp.gnu.org dead?"

    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 : Sat Aug 12 2000 - 17:26:31 EDT