From 3d8c13d953221411d5d803e76e2e6cabd506d0d4 Mon Sep 17 00:00:00 2001
From: Bart Van Assche <bart.vanassche@wdc.com>
Date: Thu, 28 Jun 2018 10:12:58 -0700
Subject: [PATCH 2/2] target: Use REQ_OP_WRITE_SAME to implement WRITE SAME
Use blkdev_submit_write_same() instead of open-coding it.
Note: as one can see in target_alloc_sgl(), the target core sets the
offset in a scatter/gather list to zero for all allocated pages.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
---
drivers/target/target_core_iblock.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
@@ -465,6 +465,8 @@ iblock_execute_write_same(struct se_cmd *cmd)
sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
sector_t sectors = target_to_linux_sector(dev,
sbc_get_write_same_sectors(cmd));
+ struct blk_plug plug;
+ int ret;
if (cmd->prot_op) {
pr_err("WRITE_SAME: Protection information with IBLOCK"
@@ -481,6 +483,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
return TCM_INVALID_CDB_FIELD;
}
+ /* 1. Use REQ_OP_WRITE_ZEROES if supported and if appropriate. */
if (bdev_write_zeroes_sectors(bdev)) {
if (!iblock_execute_zero_out(bdev, cmd))
return 0;
@@ -491,6 +494,20 @@ iblock_execute_write_same(struct se_cmd *cmd)
goto fail;
cmd->priv = ibr;
+ /* 2. Try REQ_OP_WRITE_SAME. */
+ blk_start_plug(&plug);
+ ret = blkdev_submit_write_same(bdev, block_lba, sectors, GFP_KERNEL,
+ sg_page(sg), iblock_bio_done, cmd);
+ blk_finish_plug(&plug);
+ if (ret == 0)
+ return 0;
+ if (ret != -EOPNOTSUPP)
+ goto fail;
+
+ /*
+ * 3. If neither REQ_OP_WRITE_SAME nor REQ_OP_WRITE_ZEROES are
+ * supported, use REQ_OP_WRITE.
+ */
bio = iblock_get_bio(cmd, block_lba, 1, REQ_OP_WRITE, 0);
if (!bio)
goto fail_free_ibr;
--
2.17.1