libfc: Do not invoke the response handler after fc_exch_done()
While the FCoE initiator driver invokes fc_exch_done() from inside the libfc response handler, FCoE target drivers typically invoke fc_exch_done() from outside the libfc response handler. The object fc_exch.arg points at may disappear as soon as fc_exch_done() has finished. So it's important not to invoke the response handler function after fc_exch_done() has finished. Modify libfc such that this guarantee is provided if fc_exch_done() is invoked from outside a response handler. This patch fixes a sporadic crash in FCoE target implementations after a command has been aborted. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Cc: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Robert Love <robert.w.love@intel.com>
This commit is contained in:

committed by
Robert Love

parent
f95b35cfca
commit
7030fd6261
@@ -410,6 +410,12 @@ struct fc_seq {
|
||||
* @fh_type: The frame type
|
||||
* @class: The class of service
|
||||
* @seq: The sequence in use on this exchange
|
||||
* @resp_active: Number of tasks that are concurrently executing @resp().
|
||||
* @resp_task: If @resp_active > 0, either the task executing @resp(), the
|
||||
* task that has been interrupted to execute the soft-IRQ
|
||||
* executing @resp() or NULL if more than one task is executing
|
||||
* @resp concurrently.
|
||||
* @resp_wq: Waitqueue for the tasks waiting on @resp_active.
|
||||
* @resp: Callback for responses on this exchange
|
||||
* @destructor: Called when destroying the exchange
|
||||
* @arg: Passed as a void pointer to the resp() callback
|
||||
@@ -441,6 +447,9 @@ struct fc_exch {
|
||||
u32 r_a_tov;
|
||||
u32 f_ctl;
|
||||
struct fc_seq seq;
|
||||
int resp_active;
|
||||
struct task_struct *resp_task;
|
||||
wait_queue_head_t resp_wq;
|
||||
void (*resp)(struct fc_seq *, struct fc_frame *, void *);
|
||||
void *arg;
|
||||
void (*destructor)(struct fc_seq *, void *);
|
||||
|
Reference in New Issue
Block a user