@@ -2105,7 +2105,8 @@ static char nvme_pr_type(enum pr_type type)
}
static int nvme_send_ns_head_pr_command(struct block_device *bdev,
- struct nvme_command *c, u8 *data, unsigned int data_len)
+ struct nvme_command *c, u8 *data, unsigned int data_len,
+ blk_status_t *blk_stat)
{
struct nvme_ns_head *head = bdev->bd_disk->private_data;
int srcu_idx = srcu_read_lock(&head->srcu);
@@ -2115,20 +2116,28 @@ static int nvme_send_ns_head_pr_command(struct block_device *bdev,
if (ns) {
c->common.nsid = cpu_to_le32(ns->head->ns_id);
ret = nvme_submit_sync_cmd(ns->queue, c, data, data_len);
+ if (blk_stat && ret >= 0)
+ *blk_stat = nvme_error_status(ret);
}
srcu_read_unlock(&head->srcu, srcu_idx);
return ret;
}
static int nvme_send_ns_pr_command(struct nvme_ns *ns, struct nvme_command *c,
- u8 *data, unsigned int data_len)
+ u8 *data, unsigned int data_len, blk_status_t *blk_stat)
{
+ int ret;
+
c->common.nsid = cpu_to_le32(ns->head->ns_id);
- return nvme_submit_sync_cmd(ns->queue, c, data, data_len);
+ ret = nvme_submit_sync_cmd(ns->queue, c, data, data_len);
+ if (blk_stat && ret >= 0)
+ *blk_stat = nvme_error_status(ret);
+ return ret;
}
static int nvme_pr_command(struct block_device *bdev, u32 cdw10,
- u64 key, u64 sa_key, u8 op)
+ u64 key, u64 sa_key, u8 op,
+ blk_status_t *blk_stat)
{
struct nvme_command c = { };
u8 data[16] = { 0, };
@@ -2142,9 +2151,9 @@ 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,
- sizeof(data));
- return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, data,
- sizeof(data));
+ sizeof(data), blk_stat);
+ return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c,
+ data, sizeof(data), blk_stat);
}
static int nvme_pr_register(struct block_device *bdev, u64 old,
@@ -2158,7 +2167,8 @@ static int nvme_pr_register(struct block_device *bdev, u64 old,
cdw10 = old ? 2 : 0;
cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
- return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
+ return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register,
+ blk_stat);
}
static int nvme_pr_reserve(struct block_device *bdev, u64 key,
@@ -2171,7 +2181,8 @@ static int nvme_pr_reserve(struct block_device *bdev, u64 key,
cdw10 = nvme_pr_type(type) << 8;
cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0);
- return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire);
+ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire,
+ blk_stat);
}
static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
@@ -2179,7 +2190,8 @@ static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
{
u32 cdw10 = nvme_pr_type(type) << 8 | (abort ? 2 : 1);
- return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
+ return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire,
+ blk_stat);
}
static int nvme_pr_clear(struct block_device *bdev, u64 key,
@@ -2187,7 +2199,8 @@ static int nvme_pr_clear(struct block_device *bdev, u64 key,
{
u32 cdw10 = 1 | (key ? 1 << 3 : 0);
- return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
+ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register,
+ blk_stat);
}
static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type,
@@ -2195,11 +2208,12 @@ static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type
{
u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0);
- return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release,
+ blk_stat);
}
static int nvme_pr_resv_report(struct block_device *bdev, u8 *data,
- u32 data_len, bool *eds)
+ u32 data_len, bool *eds, blk_status_t *blk_stat)
{
struct nvme_command c = { };
int ret;
@@ -2210,12 +2224,16 @@ static int nvme_pr_resv_report(struct block_device *bdev, u8 *data,
*eds = true;
retry:
+ if (blk_stat)
+ *blk_stat = 0;
+
if (IS_ENABLED(CONFIG_NVME_MULTIPATH) &&
bdev->bd_disk->fops == &nvme_ns_head_ops)
- ret = nvme_send_ns_head_pr_command(bdev, &c, data, data_len);
+ ret = nvme_send_ns_head_pr_command(bdev, &c, data, data_len,
+ blk_stat);
else
ret = nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c,
- data, data_len);
+ data, data_len, blk_stat);
if (ret == NVME_SC_HOST_ID_INCONSIST && c.common.cdw11) {
c.common.cdw11 = 0;
*eds = false;
@@ -2245,7 +2263,7 @@ static int nvme_pr_read_keys(struct block_device *bdev,
if (!data)
return -ENOMEM;
- ret = nvme_pr_resv_report(bdev, data, data_len, &eds);
+ ret = nvme_pr_resv_report(bdev, data, data_len, &eds, blk_stat);
if (ret)
goto free_data;
@@ -2286,7 +2304,7 @@ static int nvme_pr_read_reservation(struct block_device *bdev,
* the response buffer.
*/
ret = nvme_pr_resv_report(bdev, (u8 *)&tmp_status, sizeof(tmp_status),
- &eds);
+ &eds, blk_stat);
if (ret)
return 0;
@@ -2302,7 +2320,7 @@ static int nvme_pr_read_reservation(struct block_device *bdev,
if (!data)
return -ENOMEM;
- ret = nvme_pr_resv_report(bdev, data, data_len, &eds);
+ ret = nvme_pr_resv_report(bdev, data, data_len, &eds, blk_stat);
if (ret)
goto free_data;
status = (struct nvme_reservation_status *)data;
This patch has the nvme pr_ops convert from a nvme status value to a blk_status_t. Signed-off-by: Mike Christie <michael.christie@oracle.com> --- drivers/nvme/host/core.c | 54 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-)