mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
nvmet-fc: free pending reqs on tgtport unregister
When nvmet_fc_unregister_targetport is called by the LLDD, it's not possible to communicate with the host, thus all pending request will not be process. Thus explicitly free them. Signed-off-by: Daniel Wagner <wagi@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
84eedced1c
commit
bbccbf791e
|
|
@ -1583,6 +1583,39 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
|
|||
spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmet_fc_free_pending_reqs(struct nvmet_fc_tgtport *tgtport)
|
||||
{
|
||||
struct nvmet_fc_ls_req_op *lsop;
|
||||
struct nvmefc_ls_req *lsreq;
|
||||
struct nvmet_fc_ls_iod *iod;
|
||||
int i;
|
||||
|
||||
iod = tgtport->iod;
|
||||
for (i = 0; i < NVMET_LS_CTX_COUNT; iod++, i++)
|
||||
cancel_work(&iod->work);
|
||||
|
||||
/*
|
||||
* After this point the connection is lost and thus any pending
|
||||
* request can't be processed by the normal completion path. This
|
||||
* is likely a request from nvmet_fc_send_ls_req_async.
|
||||
*/
|
||||
while ((lsop = list_first_entry_or_null(&tgtport->ls_req_list,
|
||||
struct nvmet_fc_ls_req_op, lsreq_list))) {
|
||||
list_del(&lsop->lsreq_list);
|
||||
|
||||
if (!lsop->req_queued)
|
||||
continue;
|
||||
|
||||
lsreq = &lsop->ls_req;
|
||||
fc_dma_unmap_single(tgtport->dev, lsreq->rqstdma,
|
||||
(lsreq->rqstlen + lsreq->rsplen),
|
||||
DMA_BIDIRECTIONAL);
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
kfree(lsop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nvmet_fc_unregister_targetport - transport entry point called by an
|
||||
* LLDD to deregister/remove a previously
|
||||
|
|
@ -1611,13 +1644,7 @@ nvmet_fc_unregister_targetport(struct nvmet_fc_target_port *target_port)
|
|||
|
||||
flush_workqueue(nvmet_wq);
|
||||
|
||||
/*
|
||||
* should terminate LS's as well. However, LS's will be generated
|
||||
* at the tail end of association termination, so they likely don't
|
||||
* exist yet. And even if they did, it's worthwhile to just let
|
||||
* them finish and targetport ref counting will clean things up.
|
||||
*/
|
||||
|
||||
nvmet_fc_free_pending_reqs(tgtport);
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user