]> www.infradead.org Git - users/willy/xarray.git/commitdiff
scsi: sd: Keep the discard mode stable
authorLi Feng <fengli@smartx.com>
Thu, 18 Jul 2024 08:07:22 +0000 (16:07 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 3 Aug 2024 01:58:41 +0000 (21:58 -0400)
There is a scenario where a large number of discard commands are issued
when the iscsi initiator connects to the target and then performs a session
rescan operation. There is a time window, most of the commands are in UNMAP
mode, and some discard commands become WRITE SAME with UNMAP.

The discard mode has been negotiated during the SCSI probe. If the mode is
temporarily changed from UNMAP to WRITE SAME with UNMAP, an I/O ERROR may
occur because the target may not implement WRITE SAME with UNMAP. Keep the
discard mode stable to fix this issue.

Signed-off-by: Li Feng <fengli@smartx.com>
Link: https://lore.kernel.org/r/20240718080751.313102-2-fengli@smartx.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/sd.c

index 718eb91ba9a5918b314bfbf96b5848b4073263c2..699f4f9674d98f67acbbf05f4a5398e8fcac0366 100644 (file)
@@ -2711,8 +2711,6 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
                if (buffer[14] & 0x40) /* LBPRZ */
                        sdkp->lbprz = 1;
-
-               sd_config_discard(sdkp, lim, SD_LBP_WS16);
        }
 
        sdkp->capacity = lba + 1;
@@ -3365,8 +3363,6 @@ static void sd_read_block_limits(struct scsi_disk *sdkp,
                        sdkp->unmap_alignment =
                                get_unaligned_be32(&vpd->data[32]) & ~(1 << 31);
 
-               sd_config_discard(sdkp, lim, sd_discard_mode(sdkp));
-
 config_atomic:
                sdkp->max_atomic = get_unaligned_be32(&vpd->data[44]);
                sdkp->atomic_alignment = get_unaligned_be32(&vpd->data[48]);
@@ -3755,6 +3751,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
                        sd_zbc_read_zones(sdkp, &lim, buffer);
                }
 
+               sd_config_discard(sdkp, &lim, sd_discard_mode(sdkp));
+
                sd_print_capacity(sdkp, old_capacity);
 
                sd_read_write_protect_flag(sdkp, buffer);