]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nvmet-fcloop: drop response if targetport is gone
authorDaniel Wagner <wagi@kernel.org>
Wed, 7 May 2025 12:23:07 +0000 (14:23 +0200)
committerChristoph Hellwig <hch@lst.de>
Tue, 20 May 2025 03:34:26 +0000 (05:34 +0200)
When the target port is gone, the lsrsp pointer is invalid. Thus don't
call the done function anymore instead just drop the response.

This happens when the target sends a disconnect association. After this
the target starts tearing down all resources and doesn't expect any
response.

Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/target/fcloop.c

index b952672f38cbdf13703d48052c4ff490c305f7c0..4c60eaf0b653b9d86e91e48e520d525a58b7688c 100644 (file)
@@ -494,16 +494,25 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
        struct nvmet_fc_target_port *targetport = rport->targetport;
        struct fcloop_tport *tport;
 
-       memcpy(lsreq->rspaddr, lsrsp->rspbuf,
-               ((lsreq->rsplen < lsrsp->rsplen) ?
-                               lsreq->rsplen : lsrsp->rsplen));
-       lsrsp->done(lsrsp);
-
        if (!targetport) {
+               /*
+                * The target port is gone. The target doesn't expect any
+                * response anymore and the ->done call is not valid
+                * because the resources have been freed by
+                * nvmet_fc_free_pending_reqs.
+                *
+                * We end up here from delete association exchange:
+                * nvmet_fc_xmt_disconnect_assoc sends an async request.
+                */
                kmem_cache_free(lsreq_cache, tls_req);
                return 0;
        }
 
+       memcpy(lsreq->rspaddr, lsrsp->rspbuf,
+               ((lsreq->rsplen < lsrsp->rsplen) ?
+                               lsreq->rsplen : lsrsp->rsplen));
+       lsrsp->done(lsrsp);
+
        tport = targetport->private;
        spin_lock(&tport->lock);
        list_add_tail(&tls_req->ls_list, &tport->ls_list);