nvmet_fc: correct logic in disconnect queue LS handling
authorJames Smart <jsmart2021@gmail.com>
Sat, 24 Dec 2016 17:46:43 +0000 (09:46 -0800)
committerSagi Grimberg <sagi@grimberg.me>
Thu, 26 Jan 2017 15:44:21 +0000 (17:44 +0200)
Correct logic in disconnect queue LS handling.
Rework so that queue searching and error reporting is above the
section to send back a ls rjt

Signed-off-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
drivers/nvme/target/fc.c

index 173e842f19c975a4a849c4120fcfcdcee73c26c1..ba57f9852bde33b0ff3d0655d4c08313632a3a8f 100644 (file)
@@ -1314,7 +1314,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
                        (struct fcnvme_ls_disconnect_rqst *)iod->rqstbuf;
        struct fcnvme_ls_disconnect_acc *acc =
                        (struct fcnvme_ls_disconnect_acc *)iod->rspbuf;
-       struct nvmet_fc_tgt_queue *queue;
+       struct nvmet_fc_tgt_queue *queue = NULL;
        struct nvmet_fc_tgt_assoc *assoc;
        int ret = 0;
        bool del_assoc = false;
@@ -1348,7 +1348,18 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
                assoc = nvmet_fc_find_target_assoc(tgtport,
                                be64_to_cpu(rqst->associd.association_id));
                iod->assoc = assoc;
-               if (!assoc)
+               if (assoc) {
+                       if (rqst->discon_cmd.scope ==
+                                       FCNVME_DISCONN_CONNECTION) {
+                               queue = nvmet_fc_find_target_queue(tgtport,
+                                               be64_to_cpu(
+                                                       rqst->discon_cmd.id));
+                               if (!queue) {
+                                       nvmet_fc_tgt_a_put(assoc);
+                                       ret = VERR_NO_CONN;
+                               }
+                       }
+               } else
                        ret = VERR_NO_ASSOC;
        }
 
@@ -1373,21 +1384,18 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
                        FCNVME_LS_DISCONNECT);
 
 
-       if (rqst->discon_cmd.scope == FCNVME_DISCONN_CONNECTION) {
-               queue = nvmet_fc_find_target_queue(tgtport,
-                                       be64_to_cpu(rqst->discon_cmd.id));
-               if (queue) {
-                       int qid = queue->qid;
+       /* are we to delete a Connection ID (queue) */
+       if (queue) {
+               int qid = queue->qid;
 
-                       nvmet_fc_delete_target_queue(queue);
+               nvmet_fc_delete_target_queue(queue);
 
-                       /* release the get taken by find_target_queue */
-                       nvmet_fc_tgt_q_put(queue);
+               /* release the get taken by find_target_queue */
+               nvmet_fc_tgt_q_put(queue);
 
-                       /* tear association down if io queue terminated */
-                       if (!qid)
-                               del_assoc = true;
-               }
+               /* tear association down if io queue terminated */
+               if (!qid)
+                       del_assoc = true;
        }
 
        /* release get taken in nvmet_fc_find_target_assoc */