From: Greg Kroah-Hartman Date: Fri, 12 Nov 2010 22:49:19 +0000 (-0800) Subject: .32 patches X-Git-Tag: v2.6.27.56~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fe47e53dcc5aa301bb5ee26d00a6d6751dbd5482;p=thirdparty%2Fkernel%2Fstable-queue.git .32 patches --- diff --git a/queue-2.6.32/fix-race-when-removing-scsi-devices.patch b/queue-2.6.32/fix-race-when-removing-scsi-devices.patch new file mode 100644 index 00000000000..a0d49a92a42 --- /dev/null +++ b/queue-2.6.32/fix-race-when-removing-scsi-devices.patch @@ -0,0 +1,81 @@ +From 546ae796bfac6399e30da4b5af2cf7a6d0f8a4ec Mon Sep 17 00:00:00 2001 +From: Christof Schmitt +Date: Wed, 6 Oct 2010 13:19:44 +0200 +Subject: [SCSI] Fix race when removing SCSI devices + +From: Christof Schmitt + +commit 546ae796bfac6399e30da4b5af2cf7a6d0f8a4ec upstream. + +Removing SCSI devices through +echo 1 > /sys/bus/scsi/devices/ ... /delete + +while the FC transport class removes the SCSI target can lead to an +oops: + +Unable to handle kernel pointer dereference at virtual kernel address 00000000b6815000 +Oops: 0011 [#1] PREEMPT SMP DEBUG_PAGEALLOC +Modules linked in: sunrpc qeth_l3 binfmt_misc dm_multipath scsi_dh dm_mod ipv6 qeth ccwgroup [last unloaded: scsi_wait_scan] +CPU: 1 Not tainted 2.6.35.5-45.x.20100924-s390xdefault #1 +Process fc_wq_0 (pid: 861, task: 00000000b7331240, ksp: 00000000b735bac0) +Krnl PSW : 0704200180000000 00000000003ff6e4 (__scsi_remove_device+0x24/0xd0) + R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:2 PM:0 EA:3 +Krnl GPRS: 0000000000000001 0000000000000000 00000000b6815000 00000000bc24a8c0 + 00000000003ff7c8 000000000056dbb8 0000000000000002 0000000000835d80 + ffffffff00000000 0000000000001000 00000000b6815000 00000000bc24a7f0 + 00000000b68151a0 00000000b6815000 00000000b735bc20 00000000b735bbf8 +Krnl Code: 00000000003ff6d6: a7840001 brc 8,3ff6d8 + 00000000003ff6da: a7fbffd8 aghi %r15,-40 + 00000000003ff6de: e3e0f0980024 stg %r14,152(%r15) + >00000000003ff6e4: e31021200004 lg %r1,288(%r2) + 00000000003ff6ea: a71f0000 cghi %r1,0 + 00000000003ff6ee: a7a40011 brc 10,3ff710 + 00000000003ff6f2: a7390003 lghi %r3,3 + 00000000003ff6f6: c0e5ffffc8b1 brasl %r14,3f8858 +Call Trace: +([<0000000000001000>] 0x1000) + [<00000000003ff7d2>] scsi_remove_device+0x42/0x54 + [<00000000003ff8ba>] __scsi_remove_target+0xca/0xfc + [<00000000003ff99a>] __remove_child+0x3a/0x48 + [<00000000003e3246>] device_for_each_child+0x72/0xbc + [<00000000003ff93a>] scsi_remove_target+0x4e/0x74 + [<0000000000406586>] fc_rport_final_delete+0xb2/0x23c + [<000000000015d080>] worker_thread+0x200/0x344 + [<000000000016330c>] kthread+0xa0/0xa8 + [<0000000000106c1a>] kernel_thread_starter+0x6/0xc + [<0000000000106c14>] kernel_thread_starter+0x0/0xc +INFO: lockdep is turned off. +Last Breaking-Event-Address: + [<00000000003ff7cc>] scsi_remove_device+0x3c/0x54 + +The function __scsi_remove_target iterates through the SCSI devices on +the host, but it drops the host_lock before calling +scsi_remove_device. When the SCSI device is deleted from another +thread, the pointer to the SCSI device in scsi_remove_device can +become invalid. Fix this by getting a reference to the SCSI device +before dropping the host_lock to keep the SCSI device alive for the +call to scsi_remove_device. + +Signed-off-by: Christof Schmitt +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -954,10 +954,11 @@ static void __scsi_remove_target(struct + list_for_each_entry(sdev, &shost->__devices, siblings) { + if (sdev->channel != starget->channel || + sdev->id != starget->id || +- sdev->sdev_state == SDEV_DEL) ++ scsi_device_get(sdev)) + continue; + spin_unlock_irqrestore(shost->host_lock, flags); + scsi_remove_device(sdev); ++ scsi_device_put(sdev); + spin_lock_irqsave(shost->host_lock, flags); + goto restart; + } diff --git a/queue-2.6.32/fix-regressions-in-scsi_internal_device_block.patch b/queue-2.6.32/fix-regressions-in-scsi_internal_device_block.patch new file mode 100644 index 00000000000..35e27ffdfcc --- /dev/null +++ b/queue-2.6.32/fix-regressions-in-scsi_internal_device_block.patch @@ -0,0 +1,65 @@ +From 986fe6c7f50974e871b8ab5a800f5310ea25b361 Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Wed, 6 Oct 2010 03:10:59 -0500 +Subject: [SCSI] Fix regressions in scsi_internal_device_block + +From: Mike Christie + +commit 986fe6c7f50974e871b8ab5a800f5310ea25b361 upstream. + +Deleting a SCSI device on a blocked fc_remote_port (before +fast_io_fail_tmo fires) results in a hanging thread: + + STACK: + 0 schedule+1108 [0x5cac48] + 1 schedule_timeout+528 [0x5cb7fc] + 2 wait_for_common+266 [0x5ca6be] + 3 blk_execute_rq+160 [0x354054] + 4 scsi_execute+324 [0x3b7ef4] + 5 scsi_execute_req+162 [0x3b80ca] + 6 sd_sync_cache+138 [0x3cf662] + 7 sd_shutdown+138 [0x3cf91a] + 8 sd_remove+112 [0x3cfe4c] + 9 __device_release_driver+124 [0x3a08b8] +10 device_release_driver+60 [0x3a0a5c] +11 bus_remove_device+266 [0x39fa76] +12 device_del+340 [0x39d818] +13 __scsi_remove_device+204 [0x3bcc48] +14 scsi_remove_device+66 [0x3bcc8e] +15 sysfs_schedule_callback_work+50 [0x260d66] +16 worker_thread+622 [0x162326] +17 kthread+160 [0x1680b0] +18 kernel_thread_starter+6 [0x10aaea] + +During the delete, the SCSI device is in moved to SDEV_CANCEL. When +the FC transport class later calls scsi_target_unblock, this has no +effect, since scsi_internal_device_unblock ignores SCSI devics in this +state. + +It looks like all these are regressions caused by: +5c10e63c943b4c67561ddc6bf61e01d4141f881f +[SCSI] limit state transitions in scsi_internal_device_unblock + +Fix by rejecting offline and cancel in the state transition. + +Signed-off-by: Christof Schmitt +[jejb: Original patch by Christof Schmitt, modified by Mike Christie] +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -2432,7 +2432,8 @@ scsi_internal_device_unblock(struct scsi + sdev->sdev_state = SDEV_RUNNING; + else if (sdev->sdev_state == SDEV_CREATED_BLOCK) + sdev->sdev_state = SDEV_CREATED; +- else ++ else if (sdev->sdev_state != SDEV_CANCEL && ++ sdev->sdev_state != SDEV_OFFLINE) + return -EINVAL; + + spin_lock_irqsave(q->queue_lock, flags); diff --git a/queue-2.6.32/gdth-integer-overflow-in-ioctl.patch b/queue-2.6.32/gdth-integer-overflow-in-ioctl.patch new file mode 100644 index 00000000000..8224ada91d7 --- /dev/null +++ b/queue-2.6.32/gdth-integer-overflow-in-ioctl.patch @@ -0,0 +1,43 @@ +From f63ae56e4e97fb12053590e41a4fa59e7daa74a4 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 8 Oct 2010 09:03:07 +0200 +Subject: [SCSI] gdth: integer overflow in ioctl + +From: Dan Carpenter + +commit f63ae56e4e97fb12053590e41a4fa59e7daa74a4 upstream. + +gdth_ioctl_alloc() takes the size variable as an int. +copy_from_user() takes the size variable as an unsigned long. +gen.data_len and gen.sense_len are unsigned longs. +On x86_64 longs are 64 bit and ints are 32 bit. + +We could pass in a very large number and the allocation would truncate +the size to 32 bits and allocate a small buffer. Then when we do the +copy_from_user(), it would result in a memory corruption. + +Signed-off-by: Dan Carpenter +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/gdth.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/scsi/gdth.c ++++ b/drivers/scsi/gdth.c +@@ -4174,6 +4174,14 @@ static int ioc_general(void __user *arg, + ha = gdth_find_ha(gen.ionode); + if (!ha) + return -EFAULT; ++ ++ if (gen.data_len > INT_MAX) ++ return -EINVAL; ++ if (gen.sense_len > INT_MAX) ++ return -EINVAL; ++ if (gen.data_len + gen.sense_len > INT_MAX) ++ return -EINVAL; ++ + if (gen.data_len + gen.sense_len != 0) { + if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, + FALSE, &paddr))) diff --git a/queue-2.6.32/libsas-fix-ncq-mixing-with-non-ncq.patch b/queue-2.6.32/libsas-fix-ncq-mixing-with-non-ncq.patch new file mode 100644 index 00000000000..b6d7c92094d --- /dev/null +++ b/queue-2.6.32/libsas-fix-ncq-mixing-with-non-ncq.patch @@ -0,0 +1,32 @@ +From f0ad30d3d2dc924decc0e10b1ff6dc32525a5d99 Mon Sep 17 00:00:00 2001 +From: David Milburn +Date: Fri, 3 Sep 2010 17:13:03 -0500 +Subject: [SCSI] libsas: fix NCQ mixing with non-NCQ + +From: David Milburn + +commit f0ad30d3d2dc924decc0e10b1ff6dc32525a5d99 upstream. + +Some cards (like mvsas) have issue troubles if non-NCQ commands are +mixed with NCQ ones. Fix this by using the libata default NCQ check +routine which waits until all NCQ commands are complete before issuing +a non-NCQ one. The impact to cards (like aic94xx) which don't need +this logic should be minimal + +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/libsas/sas_ata.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/libsas/sas_ata.c ++++ b/drivers/scsi/libsas/sas_ata.c +@@ -346,6 +346,7 @@ static int sas_ata_scr_read(struct ata_l + static struct ata_port_operations sas_sata_ops = { + .phy_reset = sas_ata_phy_reset, + .post_internal_cmd = sas_ata_post_internal, ++ .qc_defer = ata_std_qc_defer, + .qc_prep = ata_noop_qc_prep, + .qc_issue = sas_ata_qc_issue, + .qc_fill_rtf = sas_ata_qc_fill_rtf, diff --git a/queue-2.6.32/sd-name-space-exhaustion-causes-system-hang.patch b/queue-2.6.32/sd-name-space-exhaustion-causes-system-hang.patch new file mode 100644 index 00000000000..999621651b7 --- /dev/null +++ b/queue-2.6.32/sd-name-space-exhaustion-causes-system-hang.patch @@ -0,0 +1,59 @@ +From 1a03ae0f556a931aa3747b70e44b78308f5b0590 Mon Sep 17 00:00:00 2001 +From: Michael Reed +Date: Mon, 20 Sep 2010 11:20:22 -0500 +Subject: [SCSI] sd name space exhaustion causes system hang + +From: Michael Reed + +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 +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sd.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2049,11 +2049,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; +@@ -2142,6 +2141,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; diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 6562377524f..88d886e0138 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -37,3 +37,8 @@ usb-disable-endpoints-after-unbinding-interfaces-not-before.patch usb-opticon-fix-long-standing-bugs-in-opticon-driver.patch usb-accept-some-invalid-ep0-maxpacket-values.patch ohci-work-around-for-nvidia-shutdown-problem.patch +sd-name-space-exhaustion-causes-system-hang.patch +libsas-fix-ncq-mixing-with-non-ncq.patch +gdth-integer-overflow-in-ioctl.patch +fix-race-when-removing-scsi-devices.patch +fix-regressions-in-scsi_internal_device_block.patch