linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] sd: Make discard granularity match logical block size when LBPRZ=1
@ 2015-11-13 21:46 Martin K. Petersen
  2015-11-13 21:46 ` [PATCH 2/3] block/sd: Fix device-imposed transfer length limits Martin K. Petersen
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Martin K. Petersen @ 2015-11-13 21:46 UTC (permalink / raw)
  To: linux-scsi; +Cc: Martin K. Petersen

A device may report an OPTIMAL UNMAP GRANULARITY and UNMAP GRANULARITY
ALIGNMENT in the Block Limits VPD. These parameters describe the
device's internal provisioning allocation units. By default the block
layer will round and align any discard requests based on these limits.

If a device reports LBPRZ=1 to guarantee zeroes after discard, however,
it is imperative that the block layer does not leave out any parts of
the requested block range. Otherwise the device can not do the required
zeroing of any partial allocation units and this can lead to data
corruption.

Since the dm thinp personality relies on the block layer's current
behavior and is unable to deal with partial discard blocks we work
around the problem by setting the granularity to match the logical block
size when LBPRZ is enabled.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
 drivers/scsi/sd.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3f370228bf31..c322969026bc 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -636,11 +636,24 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 	unsigned int max_blocks = 0;
 
 	q->limits.discard_zeroes_data = 0;
-	q->limits.discard_alignment = sdkp->unmap_alignment *
-		logical_block_size;
-	q->limits.discard_granularity =
-		max(sdkp->physical_block_size,
-		    sdkp->unmap_granularity * logical_block_size);
+
+	/*
+	 * When LBPRZ is reported, discard alignment and granularity
+	 * must be fixed to the logical block size. Otherwise the block
+	 * layer will drop misaligned portions of the request which can
+	 * lead to data corruption. If LBPRZ is not set, we honor the
+	 * device preference.
+	 */
+	if (sdkp->lbprz) {
+		q->limits.discard_alignment = 0;
+		q->limits.discard_granularity = 1;
+	} else {
+		q->limits.discard_alignment = sdkp->unmap_alignment *
+			logical_block_size;
+		q->limits.discard_granularity =
+			max(sdkp->physical_block_size,
+			    sdkp->unmap_granularity * logical_block_size);
+	}
 
 	sdkp->provisioning_mode = mode;
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-24 12:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-13 21:46 [PATCH 1/3] sd: Make discard granularity match logical block size when LBPRZ=1 Martin K. Petersen
2015-11-13 21:46 ` [PATCH 2/3] block/sd: Fix device-imposed transfer length limits Martin K. Petersen
2015-11-19  8:32   ` Christoph Hellwig
2015-11-13 21:46 ` [PATCH 3/3] MAINTAINERS: Add myself as co-maintainer of the SCSI subsystem Martin K. Petersen
2015-11-19  8:32   ` Christoph Hellwig
2015-11-24 12:44   ` Johannes Thumshirn
2015-11-19  8:24 ` [PATCH 1/3] sd: Make discard granularity match logical block size when LBPRZ=1 Christoph Hellwig
2015-11-24 12:52 ` Johannes Thumshirn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).