mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-23 04:54:01 +08:00
nvmet: add support for the Write Zeroes command
Add support for handling write zeroes command on target. Call into __blkdev_issue_zeroout, which the block layer expands into the best suitable variant of zeroing the LBAs. Allow write zeroes operation to deallocate the LBAs when calling __blkdev_issue_zeroout. Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@hgst.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
6d31e3ba23
commit
d262920998
@ -237,7 +237,8 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
|
|||||||
id->maxcmd = cpu_to_le16(NVMET_MAX_CMD);
|
id->maxcmd = cpu_to_le16(NVMET_MAX_CMD);
|
||||||
|
|
||||||
id->nn = cpu_to_le32(ctrl->subsys->max_nsid);
|
id->nn = cpu_to_le32(ctrl->subsys->max_nsid);
|
||||||
id->oncs = cpu_to_le16(NVME_CTRL_ONCS_DSM);
|
id->oncs = cpu_to_le16(NVME_CTRL_ONCS_DSM |
|
||||||
|
NVME_CTRL_ONCS_WRITE_ZEROES);
|
||||||
|
|
||||||
/* XXX: don't report vwc if the underlying device is write through */
|
/* XXX: don't report vwc if the underlying device is write through */
|
||||||
id->vwc = NVME_CTRL_VWC_PRESENT;
|
id->vwc = NVME_CTRL_VWC_PRESENT;
|
||||||
|
@ -170,6 +170,32 @@ static void nvmet_execute_dsm(struct nvmet_req *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nvmet_execute_write_zeroes(struct nvmet_req *req)
|
||||||
|
{
|
||||||
|
struct nvme_write_zeroes_cmd *write_zeroes = &req->cmd->write_zeroes;
|
||||||
|
struct bio *bio = NULL;
|
||||||
|
u16 status = NVME_SC_SUCCESS;
|
||||||
|
sector_t sector;
|
||||||
|
sector_t nr_sector;
|
||||||
|
|
||||||
|
sector = le64_to_cpu(write_zeroes->slba) <<
|
||||||
|
(req->ns->blksize_shift - 9);
|
||||||
|
nr_sector = (((sector_t)le32_to_cpu(write_zeroes->length)) <<
|
||||||
|
(req->ns->blksize_shift - 9)) + 1;
|
||||||
|
|
||||||
|
if (__blkdev_issue_zeroout(req->ns->bdev, sector, nr_sector,
|
||||||
|
GFP_KERNEL, &bio, true))
|
||||||
|
status = NVME_SC_INTERNAL | NVME_SC_DNR;
|
||||||
|
|
||||||
|
if (bio) {
|
||||||
|
bio->bi_private = req;
|
||||||
|
bio->bi_end_io = nvmet_bio_done;
|
||||||
|
submit_bio(bio);
|
||||||
|
} else {
|
||||||
|
nvmet_req_complete(req, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int nvmet_parse_io_cmd(struct nvmet_req *req)
|
int nvmet_parse_io_cmd(struct nvmet_req *req)
|
||||||
{
|
{
|
||||||
struct nvme_command *cmd = req->cmd;
|
struct nvme_command *cmd = req->cmd;
|
||||||
@ -207,6 +233,9 @@ int nvmet_parse_io_cmd(struct nvmet_req *req)
|
|||||||
req->data_len = le32_to_cpu(cmd->dsm.nr + 1) *
|
req->data_len = le32_to_cpu(cmd->dsm.nr + 1) *
|
||||||
sizeof(struct nvme_dsm_range);
|
sizeof(struct nvme_dsm_range);
|
||||||
return 0;
|
return 0;
|
||||||
|
case nvme_cmd_write_zeroes:
|
||||||
|
req->execute = nvmet_execute_write_zeroes;
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
pr_err("nvmet: unhandled cmd %d\n", cmd->common.opcode);
|
pr_err("nvmet: unhandled cmd %d\n", cmd->common.opcode);
|
||||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||||
|
Loading…
Reference in New Issue
Block a user