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: Minwoo Im <minwoo.im.dev@gmail.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: James Smart <james.smart@broadcom.com> Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
This commit is contained in:
parent
2f9c173647
commit
331813f687
@ -1096,10 +1096,9 @@ static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *n
|
||||
NVME_IDENTIFY_DATA_SIZE);
|
||||
}
|
||||
|
||||
static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl,
|
||||
unsigned nsid)
|
||||
static int nvme_identify_ns(struct nvme_ctrl *ctrl,
|
||||
unsigned nsid, struct nvme_id_ns **id)
|
||||
{
|
||||
struct nvme_id_ns *id;
|
||||
struct nvme_command c = { };
|
||||
int error;
|
||||
|
||||
@ -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.cns = NVME_ID_CNS_NS;
|
||||
|
||||
id = kmalloc(sizeof(*id), GFP_KERNEL);
|
||||
if (!id)
|
||||
return NULL;
|
||||
*id = kmalloc(sizeof(**id), GFP_KERNEL);
|
||||
if (!*id)
|
||||
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) {
|
||||
dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error);
|
||||
kfree(id);
|
||||
return NULL;
|
||||
kfree(*id);
|
||||
}
|
||||
|
||||
return id;
|
||||
return error;
|
||||
}
|
||||
|
||||
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)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
id = nvme_identify_ns(ctrl, ns->head->ns_id);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
ret = nvme_identify_ns(ctrl, ns->head->ns_id, &id);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (id->ncap == 0) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
goto free_id;
|
||||
}
|
||||
|
||||
__nvme_revalidate_disk(disk, id);
|
||||
@ -1757,8 +1755,11 @@ static int nvme_revalidate_disk(struct gendisk *disk)
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
out:
|
||||
free_id:
|
||||
kfree(id);
|
||||
out:
|
||||
if (ret > 0)
|
||||
ret = blk_status_to_errno(nvme_error_status(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
nvme_set_queue_limits(ctrl, ns->queue);
|
||||
|
||||
id = nvme_identify_ns(ctrl, nsid);
|
||||
if (!id) {
|
||||
ret = -EIO;
|
||||
ret = nvme_identify_ns(ctrl, nsid, &id);
|
||||
if (ret)
|
||||
goto out_free_queue;
|
||||
}
|
||||
|
||||
if (id->ncap == 0) {
|
||||
ret = -EINVAL;
|
||||
@ -3395,6 +3394,8 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
|
||||
blk_cleanup_queue(ns->queue);
|
||||
out_free_ns:
|
||||
kfree(ns);
|
||||
if (ret > 0)
|
||||
ret = blk_status_to_errno(nvme_error_status(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user