提交 c8de7203 编写于 作者: S Sagi Grimberg 提交者: Yang Yingliang

nvme: make nvme_identify_ns propagate errors back

mainline inclusion
from mainline-v5.4-rc1
commit 331813f6
category: bugfix
bugzilla: NA
CVE: NA
Link: https://gitee.com/openeuler/kernel/issues/I1WGZE

--------------------------------

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: NMinwoo Im <minwoo.im.dev@gmail.com>
Reviewed-by: NHannes Reinecke <hare@suse.com>
Reviewed-by: NJames Smart <james.smart@broadcom.com>
Reviewed-by: NChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
Signed-off-by: NSagi Grimberg <sagi@grimberg.me>
Reviewed-by: NChao Leng <lengchao@huawei.com>
Reviewed-by: NJike Cheng <chengjike.cheng@huawei.com>
Signed-off-by: NLijie <lijie34@huawei.com>
Reviewed-by: NTao Hou <houtao1@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 0728af6f
...@@ -1051,10 +1051,9 @@ static int nvme_identify_ns_list(struct nvme_ctrl *dev, unsigned nsid, __le32 *n ...@@ -1051,10 +1051,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;
...@@ -1063,18 +1062,17 @@ static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl, ...@@ -1063,18 +1062,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\n"); dev_warn(ctrl->device, "Identify namespace failed\n");
kfree(id); kfree(*id);
return NULL;
} }
return id; return error;
} }
static int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, static int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11,
...@@ -1628,13 +1626,13 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1628,13 +1626,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);
...@@ -1645,8 +1643,11 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1645,8 +1643,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;
} }
...@@ -3176,7 +3177,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -3176,7 +3177,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
struct gendisk *disk; struct gendisk *disk;
struct nvme_id_ns *id; struct nvme_id_ns *id;
char disk_name[DISK_NAME_LEN]; char disk_name[DISK_NAME_LEN];
int node = dev_to_node(ctrl->dev), flags = GENHD_FL_EXT_DEVT; int node = dev_to_node(ctrl->dev), flags = GENHD_FL_EXT_DEVT, ret;
ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node); ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
if (!ns) if (!ns)
...@@ -3195,8 +3196,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -3195,8 +3196,8 @@ static void 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)
goto out_free_queue; goto out_free_queue;
if (id->ncap == 0) if (id->ncap == 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册