Failing wihtout notifying is really evil.And thats the
issue I had in my mind when  talks where going on
regarding SCSI hotpluggable too.And far as race
condition is concerned,i think for any driver it will 
be really a problem in case of SMP systems where it is
very prone for race conditions.I think this patch
serves the purpose.
thanx


--- Oliver Neukum <[EMAIL PROTECTED]>
wrote:
> Hi list,
> 
> as the big kernel lock is no longer held during
> open, scsi_unregister_module 
> races with open. I've discussed this with David
> Hinds. It will affect the 
> pcmcia scsi drivers.
> The patch I've attached grabs the big kernel lock
> and returns error codes in 
> case unregistering fails. Failure without reporting
> is evil.
> I would really appreciate if you could comment on
> it.
> 
>       Regards
>               Oliver
> > --- linux-vanilla/drivers/scsi/scsi.c       Mon Jan  1
> 14:28:32 2001
> +++ linux/drivers/scsi/scsi.c Sat Jan  6 00:41:38
> 2001
> @@ -53,6 +53,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/smp_lock.h>
>  
>  #define __KERNEL_SYSCALLS__
>  
> @@ -1376,7 +1377,7 @@
>  }
>  
>  static int scsi_register_host(Scsi_Host_Template
> *);
> -static void scsi_unregister_host(Scsi_Host_Template
> *);
> +static int scsi_unregister_host(Scsi_Host_Template
> *);
>  
>  /*
>   * Function:    scsi_release_commandblocks()
> @@ -1963,14 +1964,8 @@
>  /*
>   * Similarly, this entry point should be called by
> a loadable module if it
>   * is trying to remove a low level scsi driver from
> the system.
> - *
> - * Note - there is a fatal flaw in the deregister
> module function.
> - * There is no way to return a code that says 'I
> cannot be unloaded now'.
> - * The system relies entirely upon usage counts
> that are maintained,
> - * and the assumption is that if the usage count is
> 0, then the module
> - * can be unloaded.
>   */
> -static void scsi_unregister_host(Scsi_Host_Template
> * tpnt)
> +static int scsi_unregister_host(Scsi_Host_Template
> * tpnt)
>  {
>       int online_status;
>       int pcount0, pcount;
> @@ -1982,6 +1977,9 @@
>       struct Scsi_Host *shpnt;
>       char name[10];  /* host_no>=10^9? I don't think so.
> */
>  
> +     /* get the big kernel lock, so we don't race with
> open() */
> +     lock_kernel();
> +
>       /*
>        * First verify that this host adapter is
> completely free with no pending
>        * commands 
> @@ -1992,7 +1990,7 @@
>                       if (SDpnt->host->hostt == tpnt
>                           && SDpnt->host->hostt->module
>                           &&
> GET_USE_COUNT(SDpnt->host->hostt->module))
> -                             return;
> +                             goto err_out;
>                       /* 
>                        * FIXME(eric) - We need to find a way to notify
> the
>                        * low level driver that we are shutting down -
> via the
> @@ -2044,7 +2042,7 @@
>                                       }
>                                       SDpnt->online = online_status;
>                                       printk(KERN_ERR "Device busy???\n");
> -                                     return;
> +                                     goto err_out;
>                               }
>                               /*
>                                * No, this device is really free.  Mark it as
> such, and
> @@ -2070,7 +2068,7 @@
>                       /* If something still attached, punt */
>                       if (SDpnt->attached) {
>                               printk(KERN_ERR "Attached usage count = %d\n",
> SDpnt->attached);
> -                             return;
> +                             goto err_out;
>                       }
>                       devfs_unregister (SDpnt->de);
>               }
> @@ -2178,6 +2176,13 @@
>               }
>       }
>       MOD_DEC_USE_COUNT;
> +
> +     unlock_kernel();
> +     return 0;
> +
> +err_out:
> +     unlock_kernel();
> +     return -1;
>  }
>  
>  static int scsi_unregister_device(struct
> Scsi_Device_Template *tpnt);
> @@ -2259,12 +2264,13 @@
>       struct Scsi_Host *shpnt;
>       struct Scsi_Device_Template *spnt;
>       struct Scsi_Device_Template *prev_spnt;
> -
> +     
> +     lock_kernel();
>       /*
>        * If we are busy, this is not going to fly.
>        */
>       if (GET_USE_COUNT(tpnt->module) != 0)
> -             return 0;
> +             goto error_out;
>  
>       /*
>        * Next, detach the devices from the driver.
> @@ -2301,11 +2307,15 @@
>               prev_spnt->next = spnt->next;
>  
>       MOD_DEC_USE_COUNT;
> +     unlock_kernel();
>       /*
>        * Final cleanup for the driver is done in the
> driver sources in the
>        * cleanup function.
>        */
>       return 0;
> +error_out:
> +     unlock_kernel();
> +     return -1;
>  }
>  
>  
> @@ -2342,22 +2352,24 @@
>  
>  /* Reverse the actions taken above
>   */
> -void scsi_unregister_module(int module_type, void
> *ptr)
> +int scsi_unregister_module(int module_type, void
> *ptr)
>  {
> +     int retval = 0;
> +
>       switch (module_type) {
>       case MODULE_SCSI_HA:
> -             scsi_unregister_host((Scsi_Host_Template *) ptr);
> +             retval = scsi_unregister_host((Scsi_Host_Template
> *) ptr);
>               break;
>       case MODULE_SCSI_DEV:
> -             scsi_unregister_device((struct
> Scsi_Device_Template *) ptr);
> -             break;
> +             retval = scsi_unregister_device((struct
> Scsi_Device_Template *)ptr);
> +             break;
>               /* The rest of these are not yet implemented. */
>       case MODULE_SCSI_CONST:
>       case MODULE_SCSI_IOCTL:
>               break;
>       default:
>       }
> -     return;
> +     return retval;
>  }
>  
>  #ifdef CONFIG_PROC_FS
> 


__________________________________________________
Do You Yahoo!?
Yahoo! Auctions - Buy the things you want at great prices. 
http://auctions.yahoo.com/
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]

Reply via email to