[PATCH 1/3] scsi: sd: disable discard when set target full provisioning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When the target lun is set to full provisioning, the kernel
cannot perceive this change, so the kernel still thinks the
device supports the discard feature.

Discard will be disabled only after encountering a discard
IO error (a fully provisioned logical unit does not support
logical block provisioning management, so subsequent discard
IO will fail) or reconnection.

To fix this issue, we can disable device discard feature as
soon as possible during the iSCSI initiator rescanning session.

Specifically, we can reset lbpme bit 0 during the SCSI probe
if found the target lun does not support lbpm, then adjust the
discard mode to SD_LBP_DISABLE.

With this patch, the kernel can sync whether the target lun
supports logical block provisioning management after the iSCSI
initiator rescanning session, without IO error or reconnection.

Signed-off-by: Haoqian He <haoqian.he@xxxxxxxxxx>
Signed-off-by: Li Feng <fengli@xxxxxxxxxx>
---
 drivers/scsi/sd.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 548c74ecc836..44a19945b5b6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2709,6 +2709,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
 		if (buffer[14] & 0x40) /* LBPRZ */
 			sdkp->lbprz = 1;
+	} else {
+		sdkp->lbpme = 0;
+		sdkp->lbprz = 0;
 	}
 
 	sdkp->capacity = lba + 1;
@@ -3303,12 +3306,9 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
 
 static unsigned int sd_discard_mode(struct scsi_disk *sdkp)
 {
-	if (!sdkp->lbpvpd) {
-		/* LBP VPD page not provided */
-		if (sdkp->max_unmap_blocks)
-			return SD_LBP_UNMAP;
-		return SD_LBP_WS16;
-	}
+	if (!sdkp->lbpvpd)
+		/* Disable discard if LBP VPD page not provided */
+		return SD_LBP_DISABLE;
 
 	/* LBP VPD page tells us what to use */
 	if (sdkp->lbpu && sdkp->max_unmap_blocks)
@@ -3343,8 +3343,12 @@ static void sd_read_block_limits(struct scsi_disk *sdkp,
 
 		sdkp->max_ws_blocks = (u32)get_unaligned_be64(&vpd->data[36]);
 
-		if (!sdkp->lbpme)
+		if (!sdkp->lbpme) {
+			sdkp->max_unmap_blocks = 0;
+			sdkp->unmap_granularity = 0;
+			sdkp->unmap_alignment = 0;
 			goto config_atomic;
+		}
 
 		lba_count = get_unaligned_be32(&vpd->data[20]);
 		desc_count = get_unaligned_be32(&vpd->data[24]);
@@ -3425,8 +3429,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp)
 {
 	struct scsi_vpd *vpd;
 
-	if (sdkp->lbpme == 0)
+	if (!sdkp->lbpme) {
+		sdkp->lbpvpd    = 0;
+		sdkp->lbpu      = 0;
+		sdkp->lbpws     = 0;
+		sdkp->lbpws10   = 0;
 		return;
+	}
 
 	rcu_read_lock();
 	vpd = rcu_dereference(sdkp->device->vpd_pgb2);
-- 
2.44.0





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux