diff options
author | Joern Engel <joern@logfs.org> | 2011-10-27 18:44:46 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-11-02 11:56:41 -0400 |
commit | b8a11d7399173dcf23b6d0ca4f416bdf1eba982e (patch) | |
tree | 18d1c607b6aaad5e082a1ffd4d0c5406ff9482a3 /drivers | |
parent | abc1fd4f92d86168790a9eaf9834713a41da788e (diff) |
target: Avoid double list_del for aborted se_tmr_req
After the list_del() in core_tmr_drain_tmr_list(),
core_tmr_release_req() would list_del() the same object again.
Call graph:
core_tmr_drain_tmr_list
transport_cmd_finish_abort_tmr
transport_generic_remove
transport_free_se_cmd
core_tmr_release_req
So use list_del_init(), as list_del() of an initialized list_head is
safe and essentially a nop. In the CONFIG_DEBUG_LIST case, list_del()
actually poisons the list_head, but that is fine as we free the object
directly afterwards.
Signed-off-by: Joern Engel <joern@logfs.org>
Cc: stable@kernel.org
Signed-off-by: Nicholas Bellinger <nab@risingtidesystems.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_tmr.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 2b0c528c1dd9..b1b9f2d6f935 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -152,7 +152,7 @@ static void core_tmr_drain_tmr_list( | |||
152 | spin_unlock_irqrestore(&dev->se_tmr_lock, flags); | 152 | spin_unlock_irqrestore(&dev->se_tmr_lock, flags); |
153 | 153 | ||
154 | list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) { | 154 | list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) { |
155 | list_del(&tmr_p->tmr_list); | 155 | list_del_init(&tmr_p->tmr_list); |
156 | cmd = tmr_p->task_cmd; | 156 | cmd = tmr_p->task_cmd; |
157 | 157 | ||
158 | pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x," | 158 | pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x," |