Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+20 −19
Original line number Original line Diff line number Diff line
@@ -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,
	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)
		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)
		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)
	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)
	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;
}
}