Skip to content

Commit 715ea9e

Browse files
Christoph Hellwigaxboe
authored andcommitted
nvme: fix and clarify the check for missing metadata
Update the check in nvme_setup_rw for missing metadata so that it is together with the other metadata handling, does not contain impossible to reach conditions and warns if we get an impossible requests for a (non-PI) metadata-enabled namespace when CONFIG_BLK_DEV_INTEGRITY is not set. Also add a little helper that checks if a given metadata configuration contains protection information Signed-off-by: Christoph Hellwig <[email protected]> Reported-by: Javier González <[email protected]> Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 24b0b58 commit 715ea9e

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

drivers/nvme/host/core.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl)
137137
}
138138
EXPORT_SYMBOL_GPL(nvme_delete_ctrl_sync);
139139

140+
static inline bool nvme_ns_has_pi(struct nvme_ns *ns)
141+
{
142+
return ns->pi_type && ns->ms == sizeof(struct t10_pi_tuple);
143+
}
144+
140145
static blk_status_t nvme_error_status(struct request *req)
141146
{
142147
switch (nvme_req(req)->status & 0x7ff) {
@@ -472,16 +477,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
472477
u16 control = 0;
473478
u32 dsmgmt = 0;
474479

475-
/*
476-
* If formated with metadata, require the block layer provide a buffer
477-
* unless this namespace is formated such that the metadata can be
478-
* stripped/generated by the controller with PRACT=1.
479-
*/
480-
if (ns && ns->ms &&
481-
(!ns->pi_type || ns->ms != sizeof(struct t10_pi_tuple)) &&
482-
!blk_integrity_rq(req) && !blk_rq_is_passthrough(req))
483-
return BLK_STS_NOTSUPP;
484-
485480
if (req->cmd_flags & REQ_FUA)
486481
control |= NVME_RW_FUA;
487482
if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD))
@@ -500,6 +495,18 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
500495
nvme_assign_write_stream(ctrl, req, &control, &dsmgmt);
501496

502497
if (ns->ms) {
498+
/*
499+
* If formated with metadata, the block layer always provides a
500+
* metadata buffer if CONFIG_BLK_DEV_INTEGRITY is enabled. Else
501+
* we enable the PRACT bit for protection information or set the
502+
* namespace capacity to zero to prevent any I/O.
503+
*/
504+
if (!blk_integrity_rq(req)) {
505+
if (WARN_ON_ONCE(!nvme_ns_has_pi(ns)))
506+
return BLK_STS_NOTSUPP;
507+
control |= NVME_RW_PRINFO_PRACT;
508+
}
509+
503510
switch (ns->pi_type) {
504511
case NVME_NS_DPS_PI_TYPE3:
505512
control |= NVME_RW_PRINFO_PRCHK_GUARD;
@@ -512,8 +519,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
512519
nvme_block_nr(ns, blk_rq_pos(req)));
513520
break;
514521
}
515-
if (!blk_integrity_rq(req))
516-
control |= NVME_RW_PRINFO_PRACT;
517522
}
518523

519524
cmnd->rw.control = cpu_to_le16(control);
@@ -1173,7 +1178,7 @@ static void nvme_update_disk_info(struct gendisk *disk,
11731178
if (ns->ms && !ns->ext &&
11741179
(ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
11751180
nvme_init_integrity(disk, ns->ms, ns->pi_type);
1176-
if (ns->ms && !(ns->ms == 8 && ns->pi_type) && !blk_get_integrity(disk))
1181+
if (ns->ms && !nvme_ns_has_pi(ns) && !blk_get_integrity(disk))
11771182
capacity = 0;
11781183
set_capacity(disk, capacity);
11791184

0 commit comments

Comments
 (0)