| From 0278ccd9d53e07c4e699432b2fed9de6c56f506c Mon Sep 17 00:00:00 2001 |
| From: Chris Boot <bootc@bootc.net> |
| Date: Mon, 22 Aug 2011 21:38:38 +0100 |
| Subject: firewire: sbp2: fix panic after rmmod with slow targets |
| |
| From: Chris Boot <bootc@bootc.net> |
| |
| commit 0278ccd9d53e07c4e699432b2fed9de6c56f506c upstream. |
| |
| If firewire-sbp2 starts a login to a target that doesn't complete ORBs |
| in a timely manner (and has to retry the login), and the module is |
| removed before the operation times out, you end up with a null-pointer |
| dereference and a kernel panic. |
| |
| [SR: This happens because sbp2_target_get/put() do not maintain |
| module references. scsi_device_get/put() do, but at occasions like |
| Chris describes one, nobody holds a reference to an SBP-2 sdev.] |
| |
| This patch cancels pending work for each unit in sbp2_remove(), which |
| hopefully means there are no extra references around that prevent us |
| from unloading. This fixes my crash. |
| |
| Signed-off-by: Chris Boot <bootc@bootc.net> |
| Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/firewire/sbp2.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/drivers/firewire/sbp2.c |
| +++ b/drivers/firewire/sbp2.c |
| @@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *de |
| { |
| struct fw_unit *unit = fw_unit(dev); |
| struct sbp2_target *tgt = dev_get_drvdata(&unit->device); |
| + struct sbp2_logical_unit *lu; |
| + |
| + list_for_each_entry(lu, &tgt->lu_list, link) |
| + cancel_delayed_work_sync(&lu->work); |
| |
| sbp2_target_put(tgt); |
| return 0; |