| From 1a03ae0f556a931aa3747b70e44b78308f5b0590 Mon Sep 17 00:00:00 2001 |
| From: Michael Reed <mdr@sgi.com> |
| Date: Mon, 20 Sep 2010 11:20:22 -0500 |
| Subject: [SCSI] sd name space exhaustion causes system hang |
| |
| From: Michael Reed <mdr@sgi.com> |
| |
| commit 1a03ae0f556a931aa3747b70e44b78308f5b0590 upstream. |
| |
| Following a site power outage which re-enabled all the ports on my FC |
| switches, my system subsequently booted with far too many luns! I had |
| let it run hoping it would make multi-user. It didn't. :( It hung solid |
| after exhausting the last sd device, sdzzz, and attempting to create sdaaaa |
| and beyond. I was unable to get a dump. |
| |
| Discovered using a 2.6.32.13 based system. |
| |
| correct this by detecting when the last index is utilized and failing |
| the sd probe of the device. Patch applies to scsi-misc-2.6. |
| |
| Signed-off-by: Michael Reed <mdr@sgi.com> |
| Signed-off-by: James Bottomley <James.Bottomley@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/scsi/sd.c | 15 ++++++++++----- |
| 1 file changed, 10 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/scsi/sd.c |
| +++ b/drivers/scsi/sd.c |
| @@ -2156,11 +2156,10 @@ static void sd_probe_async(void *data, a |
| index = sdkp->index; |
| dev = &sdp->sdev_gendev; |
| |
| - if (index < SD_MAX_DISKS) { |
| - gd->major = sd_major((index & 0xf0) >> 4); |
| - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
| - gd->minors = SD_MINORS; |
| - } |
| + gd->major = sd_major((index & 0xf0) >> 4); |
| + gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
| + gd->minors = SD_MINORS; |
| + |
| gd->fops = &sd_fops; |
| gd->private_data = &sdkp->driver; |
| gd->queue = sdkp->device->request_queue; |
| @@ -2249,6 +2248,12 @@ static int sd_probe(struct device *dev) |
| if (error) |
| goto out_put; |
| |
| + if (index >= SD_MAX_DISKS) { |
| + error = -ENODEV; |
| + sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n"); |
| + goto out_free_index; |
| + } |
| + |
| error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); |
| if (error) |
| goto out_free_index; |