]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
nvme: fix ns removal hang when failing to revalidate due to a transient error
authorSagi Grimberg <sagi@grimberg.me>
Fri, 30 Aug 2019 18:00:59 +0000 (11:00 -0700)
committerSagi Grimberg <sagi@grimberg.me>
Thu, 12 Sep 2019 15:50:45 +0000 (08:50 -0700)
If a controller reset is racing with a namespace revalidation, the
revalidation (admin) I/O will surely fail, but we should not remove the
namespace as we will execute the I/O when the controller is back up.
Same for spurious allocation errors (return -ENOMEM).

Fix this by checking the specific error code in nvme_revalidate_disk and
if it is a transient error (for example non DNR nvme statuses or
a negative ENOMEM as allocation failure), do not remove the namespace as
it will either recover when the controller is back up and schedule
a subsequent scan, or the controller is going away and the namespaces
will be removed anyways.

This fixes a hang namespace scanning racing with a controller reset and
also sporious I/O errors in path failover coditions where the
controller reset is racing with the namespace scan work with multipath
enabled.

Reported-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
drivers/nvme/host/core.c

index f15a77dd311583c3fb18cca5eacf7d2cca2a9067..fad04282148d0c22ecfc3bb1d018cc157b8fab5e 100644 (file)
@@ -1765,7 +1765,13 @@ static int nvme_revalidate_disk(struct gendisk *disk)
 free_id:
        kfree(id);
 out:
-       if (ret > 0)
+       /*
+        * Only fail the function if we got a fatal error back from the
+        * device, otherwise ignore the error and just move on.
+        */
+       if (ret == -ENOMEM || (ret > 0 && !(ret & NVME_SC_DNR)))
+               ret = 0;
+       else if (ret > 0)
                ret = blk_status_to_errno(nvme_error_status(ret));
        return ret;
 }