Message ID | 1282232941-9910-7-git-send-email-martin.petersen@oracle.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
On Thu, Aug 19, 2010 at 11:49:01AM -0400, Martin K. Petersen wrote: > + if (sdkp->tpu && desc_count && lba_count) > + sdkp->unmap = 1; > + else if (!sdkp->tpws) { > + sd_printk(KERN_ERR, sdkp, "Thin provisioning is " \ > + "enabled but neither TPU, nor TPWS are " \ > + "set. Disabling discard!\n"); > + goto out; > + } > + I don't think we can simply break all existing setups with support for earlier SBC drafts. I think we should use the TPU and TPWS same bits if present and else fall back to our current heuristics. -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>>> "hch" == Christoph Hellwig <hch@lst.de> writes:
hch> I don't think we can simply break all existing setups with support
hch> for earlier SBC drafts. I think we should use the TPU and TPWS
hch> same bits if present and else fall back to our current heuristics.
Originally my patch included support for "legacy" TP devices triggered
by TPE=1 but no TP VPD page listed in page 0. I also supported the even
older TP approach (WRITE SAME without the UNMAP bit, all zero payload).
However, I talked to a few partners and everybody were going to add the
TP VPD to their firmware builds right away. So I ripped out the compat
stuff because I felt it was weird to have explicit support for an
intermediate SBC3 release in there.
How would you feel about a sysfs switch to "force" TP on for devices
that don't report it correctly?
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8802e48..7d6a61c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1991,14 +1991,19 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) lba_count = get_unaligned_be32(&buffer[20]); desc_count = get_unaligned_be32(&buffer[24]); - if (lba_count) { + if (sdkp->tpu && desc_count && lba_count) + sdkp->unmap = 1; + else if (!sdkp->tpws) { + sd_printk(KERN_ERR, sdkp, "Thin provisioning is " \ + "enabled but neither TPU, nor TPWS are " \ + "set. Disabling discard!\n"); + goto out; + } + + if (lba_count) q->limits.max_discard_sectors = lba_count * sector_sz >> 9; - if (desc_count) - sdkp->unmap = 1; - } - granularity = get_unaligned_be32(&buffer[28]); if (granularity) @@ -2039,6 +2044,30 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) kfree(buffer); } +/** + * sd_read_thin_provisioning - Query thin provisioning VPD page + * @disk: disk to query + */ +static void sd_read_thin_provisioning(struct scsi_disk *sdkp) +{ + unsigned char *buffer; + const int vpd_len = 8; + + if (sdkp->thin_provisioning == 0) + return; + + buffer = kmalloc(vpd_len, GFP_KERNEL); + + if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) + goto out; + + sdkp->tpu = (buffer[5] >> 7) & 1; /* UNMAP */ + sdkp->tpws = (buffer[5] >> 6) & 1; /* WRITE SAME(16) with UNMAP */ + + out: + kfree(buffer); +} + static int sd_try_extended_inquiry(struct scsi_device *sdp) { /* @@ -2090,6 +2119,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_capacity(sdkp, buffer); if (sd_try_extended_inquiry(sdp)) { + sd_read_thin_provisioning(sdkp); sd_read_block_limits(sdkp); sd_read_block_characteristics(sdkp); } diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 43d3caf..9646062 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -62,6 +62,8 @@ struct scsi_disk { unsigned first_scan : 1; unsigned thin_provisioning : 1; unsigned unmap : 1; + unsigned tpws : 1; + unsigned tpu : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
Add support for the Thin Provisioning VPD page and use the TPU and TPWS bits to switch between UNMAP and WRITE SAME(16) for discards. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> --- drivers/scsi/sd.c | 40 +++++++++++++++++++++++++++++++++++----- drivers/scsi/sd.h | 2 ++ 2 files changed, 37 insertions(+), 5 deletions(-)