Not all devices can support verify requests which can be mapped to the controller specific command. This patch adds a way to emulate REQ_OP_VERIFY for NVMeOF block device namespace. Signed-off-by: Chaitanya Kulkarni <kch@xxxxxxxxxx> --- drivers/nvme/target/io-cmd-bdev.c | 48 ++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 82c341f90f06..aec287d3b7d7 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -446,35 +446,63 @@ static void nvmet_bdev_execute_write_zeroes(struct nvmet_req *req) } } -static void nvmet_bdev_execute_verify(struct nvmet_req *req) +static void __nvmet_req_to_verify_sectors(struct nvmet_req *req, + sector_t *sects, sector_t *nr_sects) { struct nvme_verify_cmd *verify = &req->cmd->verify; + + *sects = le64_to_cpu(verify->slba) << (req->ns->blksize_shift - 9); + *nr_sects = (((sector_t)le16_to_cpu(verify->length) + 1) << + (req->ns->blksize_shift - 9)); +} + +static void nvmet_bdev_submit_emulate_verify(struct nvmet_req *req) +{ + sector_t nr_sector; + sector_t sector; + int ret = 0; + + __nvmet_req_to_verify_sectors(req, §or, &nr_sector); + if (!nr_sector) + goto out; + + /* blkdev_issue_verify() will automatically emulate */ + ret = blkdev_issue_verify(req->ns->bdev, sector, nr_sector, + GFP_KERNEL); +out: + nvmet_req_complete(req, + blk_to_nvme_status(req, errno_to_blk_status(ret))); +} + +static void nvmet_bdev_execute_verify(struct nvmet_req *req) +{ struct bio *bio = NULL; sector_t nr_sector; sector_t sector; - int ret; + int ret = 0; if (!nvmet_check_transfer_len(req, 0)) return; + __nvmet_req_to_verify_sectors(req, §or, &nr_sector); + if (!nr_sector) + goto out; + if (!bdev_verify_sectors(req->ns->bdev)) { - nvmet_req_complete(req, NVME_SC_INTERNAL | NVME_SC_DNR); + nvmet_bdev_submit_emulate_verify(req); return; } - sector = le64_to_cpu(verify->slba) << (req->ns->blksize_shift - 9); - nr_sector = (((sector_t)le16_to_cpu(verify->length) + 1) << - (req->ns->blksize_shift - 9)); - ret = __blkdev_issue_verify(req->ns->bdev, sector, nr_sector, GFP_KERNEL, &bio); - if (bio) { + if (ret == 0 && bio) { bio->bi_private = req; bio->bi_end_io = nvmet_bio_done; submit_bio(bio); - } else { - nvmet_req_complete(req, errno_to_nvme_status(req, ret)); + return; } +out: + nvmet_req_complete(req, errno_to_nvme_status(req, ret)); } u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req) -- 2.29.0