diff mbox series

[v2,4/4] nvme: Convert NVMe errors to PR errors

Message ID 20221115212825.7945-5-michael.christie@oracle.com (mailing list archive)
State New, archived
Headers show
Series block/scsi/nvme: Add error codes for PR ops | expand

Commit Message

Mike Christie Nov. 15, 2022, 9:28 p.m. UTC
This converts the NVMe errors we commonly see during PR handling to PR_STS
errors or -Exyz errors. pr_ops callers can then handle scsi and nvme errors
without knowing the device types.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/nvme/host/core.c | 42 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

Comments

Chaitanya Kulkarni Nov. 16, 2022, 1:09 a.m. UTC | #1
On 11/15/22 13:28, Mike Christie wrote:
> This converts the NVMe errors we commonly see during PR handling to PR_STS
> errors or -Exyz errors. pr_ops callers can then handle scsi and nvme errors
> without knowing the device types.
> 
> Signed-off-by: Mike Christie <michael.christie@oracle.com>
> ---
>   drivers/nvme/host/core.c | 42 ++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index dc4220600585..811de141a7ee 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -2104,11 +2104,43 @@ static int nvme_send_ns_pr_command(struct nvme_ns *ns, struct nvme_command *c,
>   	return nvme_submit_sync_cmd(ns->queue, c, data, 16);
>   }
>   
> +static int nvme_sc_to_pr_err(int nvme_sc)
> +{
> +	int err;
> +
> +	if (nvme_is_path_error(nvme_sc))
> +		return PR_STS_PATH_FAILED;
> +
> +	switch (nvme_sc) {
> +	case NVME_SC_SUCCESS:
> +		err = PR_STS_SUCCESS;
> +		break;
> +	case NVME_SC_RESERVATION_CONFLICT:
> +		err = PR_STS_RESERVATION_CONFLICT;
> +		break;
> +	case NVME_SC_ONCS_NOT_SUPPORTED:
> +		err = -EOPNOTSUPP;
> +		break;
> +	case NVME_SC_BAD_ATTRIBUTES:
> +	case NVME_SC_INVALID_OPCODE:
> +	case NVME_SC_INVALID_FIELD:
> +	case NVME_SC_INVALID_NS:
> +		err = -EINVAL;
> +		break;
> +	default:
> +		err = PR_STS_IOERR;
> +		break;
> +	}
> +
> +	return err;
> +}
> +
>   

Like nvmet_bdev_parse_io_cmd() if we return directly we can remove
the local variable and break for each case [1], no big deal feel free
to ignore this comment.

Looks good.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>

-ck

[1]
static int nvme_sc_to_pr_err(int nvme_sc)
{
	if (nvme_is_path_error(nvme_sc))
		return PR_STS_PATH_FAILED;

	switch (nvme_sc) {
	case NVME_SC_SUCCESS:
		return PR_STS_SUCCESS;
	case NVME_SC_RESERVATION_CONFLICT:
		return PR_STS_RESERVATION_CONFLICT;
	case NVME_SC_ONCS_NOT_SUPPORTED:
		return -EOPNOTSUPP;
	case NVME_SC_BAD_ATTRIBUTES:
	case NVME_SC_INVALID_OPCODE:
	case NVME_SC_INVALID_FIELD:
	case NVME_SC_INVALID_NS:
		return -EINVAL;
	default:
		return PR_STS_IOERR;
	}
}
Christoph Hellwig Nov. 16, 2022, 6:40 a.m. UTC | #2
On Tue, Nov 15, 2022 at 03:28:25PM -0600, Mike Christie wrote:
> This converts the NVMe errors we commonly see during PR handling to PR_STS
> errors or -Exyz errors. pr_ops callers can then handle scsi and nvme errors
> without knowing the device types.

Looks fine, although the improvement suggested by Chaitanya would be
nice:

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index dc4220600585..811de141a7ee 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2104,11 +2104,43 @@  static int nvme_send_ns_pr_command(struct nvme_ns *ns, struct nvme_command *c,
 	return nvme_submit_sync_cmd(ns->queue, c, data, 16);
 }
 
+static int nvme_sc_to_pr_err(int nvme_sc)
+{
+	int err;
+
+	if (nvme_is_path_error(nvme_sc))
+		return PR_STS_PATH_FAILED;
+
+	switch (nvme_sc) {
+	case NVME_SC_SUCCESS:
+		err = PR_STS_SUCCESS;
+		break;
+	case NVME_SC_RESERVATION_CONFLICT:
+		err = PR_STS_RESERVATION_CONFLICT;
+		break;
+	case NVME_SC_ONCS_NOT_SUPPORTED:
+		err = -EOPNOTSUPP;
+		break;
+	case NVME_SC_BAD_ATTRIBUTES:
+	case NVME_SC_INVALID_OPCODE:
+	case NVME_SC_INVALID_FIELD:
+	case NVME_SC_INVALID_NS:
+		err = -EINVAL;
+		break;
+	default:
+		err = PR_STS_IOERR;
+		break;
+	}
+
+	return err;
+}
+
 static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
 				u64 key, u64 sa_key, u8 op)
 {
 	struct nvme_command c = { };
 	u8 data[16] = { 0, };
+	int ret;
 
 	put_unaligned_le64(key, &data[0]);
 	put_unaligned_le64(sa_key, &data[8]);
@@ -2118,8 +2150,14 @@  static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
 
 	if (IS_ENABLED(CONFIG_NVME_MULTIPATH) &&
 	    bdev->bd_disk->fops == &nvme_ns_head_ops)
-		return nvme_send_ns_head_pr_command(bdev, &c, data);
-	return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, data);
+		ret = nvme_send_ns_head_pr_command(bdev, &c, data);
+	else
+		ret = nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c,
+					      data);
+	if (ret < 0)
+		return ret;
+
+	return nvme_sc_to_pr_err(ret);
 }
 
 static int nvme_pr_register(struct block_device *bdev, u64 old,