target: Fix recursive COMPARE_AND_WRITE callback failure
authorNicholas Bellinger <nab@linux-iscsi.org>
Tue, 1 Oct 2013 23:53:10 +0000 (16:53 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Thu, 3 Oct 2013 11:24:06 +0000 (04:24 -0700)
commitd8855c154e748c9ccd7c78e6478560ed61438e7d
treee4484595a476c9811dc31a1853c28889dbfd2c50
parentb7191253b302a9b98758c3616761ae111b6264b9
target: Fix recursive COMPARE_AND_WRITE callback failure

This patch addresses a bug when compare_and_write_callback() invoked from
target_complete_ok_work() hits an failure from __target_execute_cmd() ->
cmd->execute_cmd(), that ends up calling transport_generic_request_failure()
-> compare_and_write_post(), thus causing SCF_COMPARE_AND_WRITE_POST to
incorrectly be set.

The result of this bug is that target_complete_ok_work() no longer hits
the if (!rc && !(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE_POST) check
that forces an immediate return, and instead double completes the se_cmd
in question, triggering an OOPs in the process.

This patch changes compare_and_write_post() to only set this bit when a
failure has not already occured to ensure the immediate return from within
target_complete_ok_work(), and thus allow transport_generic_request_failure()
to handle the sending of the CHECK_CONDITION exception status.

Reported-by: Thomas Glanzmann <thomas@glanzmann.de>
Tested-by: Thomas Glanzmann <thomas@glanzmann.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_sbc.c