]> git.baikalelectronics.ru Git - kernel.git/commitdiff
nvme-multipath: fix ANA state updates when a namespace is not present
authorAnton Eidelman <anton.eidelman@gmail.com>
Sun, 12 Sep 2021 18:54:57 +0000 (12:54 -0600)
committerChristoph Hellwig <hch@lst.de>
Tue, 14 Sep 2021 08:32:04 +0000 (10:32 +0200)
nvme_update_ana_state() has a deficiency that results in a failure to
properly update the ana state for a namespace in the following case:

  NSIDs in ctrl->namespaces: 1, 3,    4
  NSIDs in desc->nsids: 1, 2, 3, 4

Loop iteration 0:
    ns index = 0, n = 0, ns->head->ns_id = 1, nsid = 1, MATCH.
Loop iteration 1:
    ns index = 1, n = 1, ns->head->ns_id = 3, nsid = 2, NO MATCH.
Loop iteration 2:
    ns index = 2, n = 2, ns->head->ns_id = 4, nsid = 4, MATCH.

Where the update to the ANA state of NSID 3 is missed.  To fix this
increment n and retry the update with the same ns when ns->head->ns_id is
higher than nsid,

Signed-off-by: Anton Eidelman <anton@lightbitslabs.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
drivers/nvme/host/multipath.c

index 5d7bc58a27bd984dc7f19341dcdcf1a3d3af658d..e8ccdd398f784443241d659761414f0e622c111b 100644 (file)
@@ -600,14 +600,17 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
 
        down_read(&ctrl->namespaces_rwsem);
        list_for_each_entry(ns, &ctrl->namespaces, list) {
-               unsigned nsid = le32_to_cpu(desc->nsids[n]);
-
+               unsigned nsid;
+again:
+               nsid = le32_to_cpu(desc->nsids[n]);
                if (ns->head->ns_id < nsid)
                        continue;
                if (ns->head->ns_id == nsid)
                        nvme_update_ns_ana_state(desc, ns);
                if (++n == nr_nsids)
                        break;
+               if (ns->head->ns_id > nsid)
+                       goto again;
        }
        up_read(&ctrl->namespaces_rwsem);
        return 0;