Commit 331813f6 authored by Sagi Grimberg's avatar Sagi Grimberg

nvme: make nvme_identify_ns propagate errors back

right now callers of nvme_identify_ns only know that it failed,
but don't know why. Make nvme_identify_ns propagate the error back.
Because nvme_submit_sync_cmd may return a positive status code, we
make nvme_identify_ns receive the id by reference and return that
status up the call chain, but make sure not to leak positive nvme
status codes to the upper layers.
Reviewed-by: default avatarMinwoo Im <minwoo.im.dev@gmail.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
parent 2f9c1736
...@@ -1096,10 +1096,9 @@ static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *n ...@@ -1096,10 +1096,9 @@ static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *n
NVME_IDENTIFY_DATA_SIZE); NVME_IDENTIFY_DATA_SIZE);
} }
static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl, static int nvme_identify_ns(struct nvme_ctrl *ctrl,
unsigned nsid) unsigned nsid, struct nvme_id_ns **id)
{ {
struct nvme_id_ns *id;
struct nvme_command c = { }; struct nvme_command c = { };
int error; int error;
...@@ -1108,18 +1107,17 @@ static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl, ...@@ -1108,18 +1107,17 @@ static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl,
c.identify.nsid = cpu_to_le32(nsid); c.identify.nsid = cpu_to_le32(nsid);
c.identify.cns = NVME_ID_CNS_NS; c.identify.cns = NVME_ID_CNS_NS;
id = kmalloc(sizeof(*id), GFP_KERNEL); *id = kmalloc(sizeof(**id), GFP_KERNEL);
if (!id) if (!*id)
return NULL; return -ENOMEM;
error = nvme_submit_sync_cmd(ctrl->admin_q, &c, id, sizeof(*id)); error = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
if (error) { if (error) {
dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error); dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error);
kfree(id); kfree(*id);
return NULL;
} }
return id; return error;
} }
static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid, static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid,
...@@ -1740,13 +1738,13 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1740,13 +1738,13 @@ static int nvme_revalidate_disk(struct gendisk *disk)
return -ENODEV; return -ENODEV;
} }
id = nvme_identify_ns(ctrl, ns->head->ns_id); ret = nvme_identify_ns(ctrl, ns->head->ns_id, &id);
if (!id) if (ret)
return -ENODEV; goto out;
if (id->ncap == 0) { if (id->ncap == 0) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto free_id;
} }
__nvme_revalidate_disk(disk, id); __nvme_revalidate_disk(disk, id);
...@@ -1757,8 +1755,11 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1757,8 +1755,11 @@ static int nvme_revalidate_disk(struct gendisk *disk)
ret = -ENODEV; ret = -ENODEV;
} }
out: free_id:
kfree(id); kfree(id);
out:
if (ret > 0)
ret = blk_status_to_errno(nvme_error_status(ret));
return ret; return ret;
} }
...@@ -3329,11 +3330,9 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -3329,11 +3330,9 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
nvme_set_queue_limits(ctrl, ns->queue); nvme_set_queue_limits(ctrl, ns->queue);
id = nvme_identify_ns(ctrl, nsid); ret = nvme_identify_ns(ctrl, nsid, &id);
if (!id) { if (ret)
ret = -EIO;
goto out_free_queue; goto out_free_queue;
}
if (id->ncap == 0) { if (id->ncap == 0) {
ret = -EINVAL; ret = -EINVAL;
...@@ -3395,6 +3394,8 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -3395,6 +3394,8 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
blk_cleanup_queue(ns->queue); blk_cleanup_queue(ns->queue);
out_free_ns: out_free_ns:
kfree(ns); kfree(ns);
if (ret > 0)
ret = blk_status_to_errno(nvme_error_status(ret));
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment