lkml.org 
[lkml]   [2000]   [Sep]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From

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
raubitsj@DynaByteSystems.com


--- 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;
\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.039 / U:7.220 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site