I have seen this problem for a long time now (and it has been reported on
this list before-months ago).  My TODO list of bugs to investigate has
grown too large so I needed to get this one off my list.

the offending code is:
"linux/drivers/scsi/sd.c" 1353/1393 (test9-2)
>  for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++)
>       devfs_unregister_blkdev(SD_MAJOR(i), "sd");

This code will do nasty things if td_template.dev_max=0, namely loop for a
very long time.  The condition becomes:
>  for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++)
>  = for (i = 0; i <= (0 - 1) / 16; i++)
>  = for (i = 0; i <= 0xFFFFFFFF / 16; i++)
   
The solution seems to be to use the macros and make the loop look like:
>#define N_USED_SCSI_DISKS  (sd_template.dev_max + SCSI_DISKS_PER_MAJOR -1)
>#define N_USED_SD_MAJORS   (N_USED_SCSI_DISKS / SCSI_DISKS_PER_MAJOR)
NEW_CODE:
>  for (i = 0; i < N_USED_SD_MAJORS; i++)
>       devfs_unregister_blkdev(SD_MAJOR(i), "sd");
Seems like a good idea to use the macros that are already defined.

This offending loop seems to be in the code 4 times
(lines 1033, 1145, 1353, 1382)

I have experienced this problem in 2.4.0test kernels but a quick
inspection of 2.2.x reveals that it has the same code and probably the
same problem.

Attacted are fixes for test9-2 and 2.2.17.  This is my first patch to the
list so please give it a glance before applying.  I have tested this
patch only on a machine without scsi disks.

-jeff

  ------------------------------------------------------------------------
       Jeff Raubitschek 
       DynaByte Systems
       [EMAIL PROTECTED]


--- linux-2.2.17/drivers/scsi/sd.c      Wed Jun  7 17:26:43 2000
+++ linux.fixed/drivers/scsi/sd.c       Mon Sep 18 09:02:14 2000
@@ -1513,7 +1513,7 @@
        sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
 
     if(!sd_registered) {
-       for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+       for (i=0; i < N_USED_SD_MAJORS; i++) {
            if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) {
                printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i));
                return 1;
@@ -1586,7 +1586,7 @@
     struct gendisk *gendisk;
     int i;
 
-    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+    for (i=0; i < N_USED_SD_MAJORS; i++) {
         /* FIXME: After 2.2 we should implement multiple sd queues */
         blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST;
         if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue;
@@ -1793,7 +1793,7 @@
 
     scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
 
-    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) 
+    for (i=0; i < N_USED_SD_MAJORS; i++)
        unregister_blkdev(SD_MAJOR(i),"sd");
     
     sd_registered--;
@@ -1826,7 +1826,7 @@
        
     }
 
-    for (i=0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+    for (i=0; i < N_USED_SD_MAJORS; i++) {
         blk_dev[SD_MAJOR(i)].request_fn = NULL;
         blk_size[SD_MAJOR(i)] = NULL;
         hardsect_size[SD_MAJOR(i)] = NULL;
--- linux.buggy/drivers/scsi/sd.c       Mon Sep 18 08:42:05 2000
+++ linux/drivers/scsi/sd.c     Mon Sep 18 08:44:37 2000
@@ -1030,7 +1030,7 @@
                sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
 
        if (!sd_registered) {
-               for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; 
i++) {
+               for (i = 0; i < N_USED_SD_MAJORS; i++) {
                        if (devfs_register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) {
                                printk("Unable to get major %d for SCSI disk\n", 
SD_MAJOR(i));
                                return 1;
@@ -1142,7 +1142,7 @@
        struct gendisk *gendisk;
        int i;
 
-       for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+       for (i = 0; i < N_USED_SD_MAJORS; i++) {
                blk_dev[SD_MAJOR(i)].queue = sd_find_queue;
        }
        for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)
@@ -1350,7 +1350,7 @@
 
        scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
 
-       for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++)
+       for (i = 0; i < N_USED_SD_MAJORS; i++)
                devfs_unregister_blkdev(SD_MAJOR(i), "sd");
 
        sd_registered--;
@@ -1379,7 +1379,7 @@
                               removed > N_USED_SD_MAJORS ? "total" : "just", 
removed);
 
        }
-       for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+       for (i = 0; i < N_USED_SD_MAJORS; i++) {
                blk_size[SD_MAJOR(i)] = NULL;
                hardsect_size[SD_MAJOR(i)] = NULL;
                read_ahead[SD_MAJOR(i)] = 0;

Reply via email to