From: Hannes Reinecke <hare@suse.de>
To: James Bottomley <james.bottomley@hansenpartnership.com>
Cc: Christoph Hellwig <hch@lst.de>,
linux-scsi@vger.kernel.org, Jens Axboe <axboe@kernel.dk>,
linux-kernel@vger.kernel.org, Hannes Reinecke <hare@suse.de>,
Hannes Reinecke <hare@suse.com>
Subject: [PATCH 3/8] sd: Set chunk_sectors to zone size
Date: Fri, 31 Jul 2015 15:36:15 +0200 [thread overview]
Message-ID: <1438349780-116429-4-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1438349780-116429-1-git-send-email-hare@suse.de>
For ZBC devices I/O must not cross zone boundaries, so setup
the 'chunk_sectors' block queue setting to the zone size.
This is only valid for REPORT ZONES SAME type 2 or 3;
for other types the zone sizes might be different
for individual zones. So issue a warning if the type is
found to be different.
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/sd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/scsi/sd.h | 1 +
2 files changed, 77 insertions(+)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3b2fcb4..b5d412a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1861,6 +1861,45 @@ sd_spinup_disk(struct scsi_disk *sdkp)
}
}
+static int
+sd_zbc_report_zones(struct scsi_disk *sdkp, sector_t start_lba,
+ unsigned char *buffer, int bufflen )
+{
+ struct scsi_device *sdp = sdkp->device;
+ const int timeout = sdp->request_queue->rq_timeout
+ * SD_FLUSH_TIMEOUT_MULTIPLIER;
+ struct scsi_sense_hdr sshdr;
+ unsigned char cmd[16];
+ int result;
+
+ if (!scsi_device_online(sdp)) {
+ sd_printk(KERN_INFO, sdkp, "device not online\n");
+ return -ENODEV;
+ }
+
+ sd_printk(KERN_INFO, sdkp, "REPORT ZONES lba %zu len %d\n",
+ start_lba, bufflen);
+
+ memset(cmd, 0, 16);
+ cmd[0] = ZBC_IN;
+ cmd[1] = ZI_REPORT_ZONES;
+ put_unaligned_be64(start_lba, &cmd[2]);
+ put_unaligned_be32(bufflen, &cmd[10]);
+ memset(buffer, 0, bufflen);
+
+ result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
+ buffer, bufflen, &sshdr,
+ timeout, SD_MAX_RETRIES, NULL);
+
+ if (result) {
+ sd_printk(KERN_NOTICE, sdkp,
+ "REPORT ZONES lba %zu failed with %d/%d\n",
+ start_lba, host_byte(result), driver_byte(result));
+
+ return -EIO;
+ }
+ return 0;
+}
/*
* Determine whether disk supports Data Integrity Field.
@@ -2631,6 +2670,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, sdkp->disk->queue);
}
+ sdkp->zoned = (buffer[8] >> 4) & 3;
out:
kfree(buffer);
}
@@ -2692,6 +2732,41 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
sdkp->ws10 = 1;
}
+static void sd_read_zones(struct scsi_disk *sdkp, unsigned char *buffer)
+{
+ int retval;
+ unsigned char *desc;
+ u32 rep_len;
+ u8 same;
+ u64 zone_len;
+
+ if (sdkp->zoned != 1)
+ /* Device managed, no special handling required */
+ return;
+
+ retval = sd_zbc_report_zones(sdkp, 0, buffer, SD_BUF_SIZE);
+ if (retval < 0)
+ return;
+
+ rep_len = get_unaligned_be32(&buffer[0]);
+ same = buffer[4] & 0xf;
+ if (same != 2 && same != 3) {
+ sd_printk(KERN_WARNING, sdkp,
+ "REPORT ZONES SAME type %d not supported\n", same);
+ return;
+ }
+ if (rep_len < 64) {
+ sd_printk(KERN_WARNING, sdkp,
+ "REPORT ZONES report invalid length %u\n",
+ rep_len);
+ return;
+ }
+ /* Read the zone length from the first zone descriptor */
+ desc = &buffer[64];
+ zone_len = get_unaligned_be64(&desc[8]);
+ blk_queue_chunk_sectors(sdkp->disk->queue, zone_len);
+}
+
static int sd_try_extended_inquiry(struct scsi_device *sdp)
{
/* Attempt VPD inquiry if the device blacklist explicitly calls
@@ -2757,6 +2832,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_zones(sdkp, buffer);
}
sdkp->first_scan = 0;
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 63ba5ca..6500d51 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -93,6 +93,7 @@ struct scsi_disk {
unsigned lbpvpd : 1;
unsigned ws10 : 1;
unsigned ws16 : 1;
+ unsigned zoned: 2; /* ZONED field */
};
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
--
1.8.5.2
next prev parent reply other threads:[~2015-07-31 13:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-31 13:36 [RFC PATCH 0/8] ZBC host-managed device support Hannes Reinecke
2015-07-31 13:36 ` [PATCH 1/8] blk-sysfs: Add 'chunk_sectors' to sysfs attributes Hannes Reinecke
2015-07-31 13:36 ` [PATCH 2/8] block: update chunk_sectors in blk_stack_limits() Hannes Reinecke
2015-07-31 13:36 ` Hannes Reinecke [this message]
2015-07-31 13:36 ` [PATCH 4/8] sd: Implement new RESET_WP provisioning mode Hannes Reinecke
2015-07-31 13:36 ` [PATCH 5/8] block: Implement support for zoned block devices Hannes Reinecke
2015-07-31 13:36 ` [PATCH 6/8] block: Add 'zoned' sysfs queue attribute Hannes Reinecke
2015-07-31 13:36 ` [PATCH 7/8] block: Introduce BLKPREP_DONE Hannes Reinecke
2015-07-31 13:36 ` [PATCH 8/8] sd: Implement support for ZBC devices Hannes Reinecke
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=1438349780-116429-4-git-send-email-hare@suse.de \
--to=hare@suse.de \
--cc=axboe@kernel.dk \
--cc=hare@suse.com \
--cc=hch@lst.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.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