From: Chaitanya Kulkarni <kch@nvidia.com>
To: <linux-block@vger.kernel.org>, <linux-scsi@vger.kernel.org>,
<linux-nvme@lists.infradead.org>, <linux-xfs@vger.kernel.org>,
<linux-fsdevel@vger.kernel.org>
Cc: <axboe@kernel.dk>, <agk@redhat.com>, <song@kernel.org>,
<djwong@kernel.org>, <kbusch@kernel.org>, <hch@lst.de>,
<sagi@grimberg.me>, <jejb@linux.ibm.com>,
<martin.petersen@oracle.com>, <viro@zeniv.linux.org.uk>,
<javier@javigon.com>, <johannes.thumshirn@wdc.com>,
<bvanassche@acm.org>, <dongli.zhang@oracle.com>,
<ming.lei@redhat.com>, <willy@infradead.org>,
<jefflexu@linux.alibaba.com>, <josef@toxicpanda.com>,
<clm@fb.com>, <dsterba@suse.com>, <jack@suse.com>,
<tytso@mit.edu>, <adilger.kernel@dilger.ca>, <jlayton@kernel.org>,
<idryomov@gmail.com>, <danil.kipnis@cloud.ionos.com>,
<ebiggers@google.com>, <jinpu.wang@cloud.ionos.com>,
Chaitanya Kulkarni <kch@nvidia.com>
Subject: [PATCH V2 6/6] scsi: sd: add support for REQ_OP_VERIFY
Date: Wed, 13 Jul 2022 00:20:19 -0700 [thread overview]
Message-ID: <20220713072019.5885-7-kch@nvidia.com> (raw)
In-Reply-To: <20220713072019.5885-1-kch@nvidia.com>
Add support to handle REQ_OP_VERIFY req_op and map it on VERIFY (16)
or VERIFY (10) in the sd driver. In case SCSI command VERIFY (16) is not
supported use SCSI command VERIFY (10). Tested with scsi_debug.
Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>
---
drivers/scsi/sd.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/scsi/sd.h | 5 ++
2 files changed, 129 insertions(+)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index eb02d939dd44..8ba8bdd78ebd 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -101,6 +101,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
static void sd_config_discard(struct scsi_disk *, unsigned int);
static void sd_config_write_same(struct scsi_disk *);
+static void sd_config_verify(struct scsi_disk *sdkp);
static int sd_revalidate_disk(struct gendisk *);
static void sd_unlock_native_capacity(struct gendisk *disk);
static int sd_probe(struct device *);
@@ -519,6 +520,43 @@ max_write_same_blocks_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(max_write_same_blocks);
+static ssize_t
+max_verify_blocks_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+ return sprintf(buf, "%u\n", sdkp->max_verify_blocks);
+}
+
+static ssize_t
+max_verify_blocks_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+ struct scsi_device *sdp = sdkp->device;
+ unsigned long max;
+ int err;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
+ return -EINVAL;
+
+ err = kstrtoul(buf, 10, &max);
+
+ if (err)
+ return err;
+
+ sdkp->max_verify_blocks = max;
+
+ sd_config_verify(sdkp);
+
+ return count;
+}
+static DEVICE_ATTR_RW(max_verify_blocks);
+
static ssize_t
zoned_cap_show(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -579,6 +617,7 @@ static struct attribute *sd_disk_attrs[] = {
&dev_attr_provisioning_mode.attr,
&dev_attr_zeroing_mode.attr,
&dev_attr_max_write_same_blocks.attr,
+ &dev_attr_max_verify_blocks.attr,
&dev_attr_max_medium_access_timeouts.attr,
&dev_attr_zoned_cap.attr,
&dev_attr_max_retries.attr,
@@ -1018,6 +1057,68 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
(logical_block_size >> 9));
}
+static blk_status_t sd_setup_verify16_cmnd(struct scsi_cmnd *cmd, u64 lba,
+ u32 nr_blocks)
+{
+ cmd->cmd_len = 16;
+ cmd->cmnd[0] = VERIFY_16;
+ put_unaligned_be64(lba, &cmd->cmnd[2]);
+ put_unaligned_be32(nr_blocks, &cmd->cmnd[10]);
+ cmd->cmnd[14] = 0;
+ cmd->cmnd[15] = 0;
+
+ return BLK_STS_OK;
+}
+
+static blk_status_t sd_setup_verify10_cmnd(struct scsi_cmnd *cmd, u64 lba,
+ u32 nr_blocks)
+{
+ if (lba > 0xffffffff && nr_blocks > 0xffff)
+ return BLK_STS_NOTSUPP;
+
+ cmd->cmd_len = 10;
+ cmd->cmnd[0] = VERIFY;
+ put_unaligned_be32((u32)lba, &cmd->cmnd[2]);
+ put_unaligned_be16((u16)nr_blocks, &cmd->cmnd[6]);
+ cmd->cmnd[9] = 0;
+
+ return BLK_STS_OK;
+}
+
+static blk_status_t sd_setup_verify_cmnd(struct scsi_cmnd *cmd)
+{
+ struct request *rq = scsi_cmd_to_rq(cmd);
+ struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
+ struct scsi_device *sdp = cmd->device;
+ u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
+ u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
+
+ if (!sdkp->verify16 && !sdkp->verify10)
+ goto out;
+
+ cmd->allowed = SD_MAX_RETRIES;
+ cmd->sc_data_direction = DMA_NONE;
+ cmd->transfersize = 0;
+ /* skip veprotect / dpo / bytchk */
+ cmd->cmnd[1] = 0;
+
+ if (sdkp->verify16)
+ return sd_setup_verify16_cmnd(cmd, lba, nr_blocks);
+ if (sdkp->verify10)
+ return sd_setup_verify10_cmnd(cmd, lba, nr_blocks);
+out:
+ return BLK_STS_TARGET;
+}
+
+static void sd_config_verify(struct scsi_disk *sdkp)
+{
+ unsigned int max_verify_sectors = sdkp->max_verify_blocks;
+ unsigned int logical_bs = sdkp->device->sector_size;
+ struct request_queue *q = sdkp->disk->queue;
+
+ blk_queue_max_verify_sectors(q, max_verify_sectors * (logical_bs >> 9));
+}
+
static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd)
{
struct request *rq = scsi_cmd_to_rq(cmd);
@@ -1244,6 +1345,8 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
}
case REQ_OP_WRITE_ZEROES:
return sd_setup_write_zeroes_cmnd(cmd);
+ case REQ_OP_VERIFY:
+ return sd_setup_verify_cmnd(cmd);
case REQ_OP_FLUSH:
return sd_setup_flush_cmnd(cmd);
case REQ_OP_READ:
@@ -1935,6 +2038,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
switch (req_op(req)) {
case REQ_OP_DISCARD:
case REQ_OP_WRITE_ZEROES:
+ case REQ_OP_VERIFY:
case REQ_OP_ZONE_RESET:
case REQ_OP_ZONE_RESET_ALL:
case REQ_OP_ZONE_OPEN:
@@ -3021,6 +3125,24 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
sdkp->ws10 = 1;
}
+static void sd_read_verify(struct scsi_disk *sdkp, unsigned char *buffer)
+{
+ struct scsi_device *sdev = sdkp->device;
+
+ if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, VERIFY_16)) {
+ sd_printk(KERN_DEBUG, sdkp, "VERIFY16 supported\n");
+ sdkp->verify16 = 1;
+ sdkp->max_verify_blocks = SD_MAX_VERIFY16_BLOCKS;
+ return;
+ }
+
+ if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, VERIFY)) {
+ sd_printk(KERN_DEBUG, sdkp, "VERIFY10 supported\n");
+ sdkp->verify10 = 1;
+ sdkp->max_verify_blocks = SD_MAX_VERIFY10_BLOCKS;
+ }
+}
+
static void sd_read_security(struct scsi_disk *sdkp, unsigned char *buffer)
{
struct scsi_device *sdev = sdkp->device;
@@ -3264,6 +3386,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
sd_read_write_same(sdkp, buffer);
+ sd_read_verify(sdkp, buffer);
sd_read_security(sdkp, buffer);
sd_config_protection(sdkp);
}
@@ -3312,6 +3435,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
set_capacity_and_notify(disk, logical_to_sectors(sdp, sdkp->capacity));
sd_config_write_same(sdkp);
+ sd_config_verify(sdkp);
kfree(buffer);
/*
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 5eea762f84d1..249100e2ea1f 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -49,6 +49,8 @@ enum {
SD_MAX_XFER_BLOCKS = 0xffffffff,
SD_MAX_WS10_BLOCKS = 0xffff,
SD_MAX_WS16_BLOCKS = 0x7fffff,
+ SD_MAX_VERIFY10_BLOCKS = 0xffff,
+ SD_MAX_VERIFY16_BLOCKS = 0xffffff,
};
enum {
@@ -118,6 +120,7 @@ struct scsi_disk {
u32 max_xfer_blocks;
u32 opt_xfer_blocks;
u32 max_ws_blocks;
+ u32 max_verify_blocks;
u32 max_unmap_blocks;
u32 unmap_granularity;
u32 unmap_alignment;
@@ -145,6 +148,8 @@ struct scsi_disk {
unsigned lbpvpd : 1;
unsigned ws10 : 1;
unsigned ws16 : 1;
+ unsigned verify10 : 1;
+ unsigned verify16 : 1;
unsigned rc_basis: 2;
unsigned zoned: 2;
unsigned urswrz : 1;
--
2.29.0
next prev parent reply other threads:[~2022-07-13 7:22 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-13 7:20 [PATCH V2 0/6] block: add support for REQ_OP_VERIFY Chaitanya Kulkarni
2022-07-13 7:20 ` [PATCH V2 1/6] " Chaitanya Kulkarni
2022-07-13 7:20 ` [PATCH V2 2/6] nvme: add support for the Verify command Chaitanya Kulkarni
2022-07-13 7:20 ` [PATCH V2 3/6] nvmet: add Verify command support for bdev-ns Chaitanya Kulkarni
2022-07-13 7:20 ` [PATCH V2 4/6] nvmet: add Verify emulation " Chaitanya Kulkarni
2022-07-13 7:20 ` [PATCH V2 5/6] null_blk: add REQ_OP_VERIFY support Chaitanya Kulkarni
2022-07-13 7:20 ` Chaitanya Kulkarni [this message]
2022-07-13 12:19 ` [PATCH V2 0/6] block: add support for REQ_OP_VERIFY Matthew Wilcox
2022-07-13 15:43 ` Chaitanya Kulkarni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220713072019.5885-7-kch@nvidia.com \
--to=kch@nvidia.com \
--cc=adilger.kernel@dilger.ca \
--cc=agk@redhat.com \
--cc=axboe@kernel.dk \
--cc=bvanassche@acm.org \
--cc=clm@fb.com \
--cc=danil.kipnis@cloud.ionos.com \
--cc=djwong@kernel.org \
--cc=dongli.zhang@oracle.com \
--cc=dsterba@suse.com \
--cc=ebiggers@google.com \
--cc=hch@lst.de \
--cc=idryomov@gmail.com \
--cc=jack@suse.com \
--cc=javier@javigon.com \
--cc=jefflexu@linux.alibaba.com \
--cc=jejb@linux.ibm.com \
--cc=jinpu.wang@cloud.ionos.com \
--cc=jlayton@kernel.org \
--cc=johannes.thumshirn@wdc.com \
--cc=josef@toxicpanda.com \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=ming.lei@redhat.com \
--cc=sagi@grimberg.me \
--cc=song@kernel.org \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox