Skip to content

Commit

Permalink
scsi: sd: Reorganize DIF/DIX code to avoid calling revalidate twice
Browse files Browse the repository at this point in the history
During device discovery we ended up calling revalidate twice and thus
requested the same parameters multiple times. This was originally necessary
due to the request_queue and gendisk needing to be instantiated to
configure the block integrity profile.

Since this dependency no longer exists, reorganize the integrity probing
code so it can be run once at the end of discovery and drop the superfluous
revalidate call. Postponing the registration step involves splitting
sd_read_protection() into two functions, one to read the device protection
type and one to configure the mode of operation.

As part of this cleanup, make the printing code a bit less verbose.

Link: https://lore.kernel.org/r/20220302053559.32147-14-martin.petersen@oracle.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
martinkpetersen committed May 2, 2022
1 parent 631669a commit 1e02939
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 34 deletions.
62 changes: 33 additions & 29 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2176,40 +2176,48 @@ static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer
{
struct scsi_device *sdp = sdkp->device;
u8 type;
int ret = 0;

if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) {
sdkp->protection_type = 0;
return ret;
return 0;
}

type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */

if (type > T10_PI_TYPE3_PROTECTION)
ret = -ENODEV;
else if (scsi_host_dif_capable(sdp->host, type))
ret = 1;

if (sdkp->first_scan || type != sdkp->protection_type)
switch (ret) {
case -ENODEV:
sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \
" protection type %u. Disabling disk!\n",
type);
break;
case 1:
sd_printk(KERN_NOTICE, sdkp,
"Enabling DIF Type %u protection\n", type);
break;
case 0:
sd_printk(KERN_NOTICE, sdkp,
"Disabling DIF Type %u protection\n", type);
break;
}
if (type > T10_PI_TYPE3_PROTECTION) {
sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \
" protection type %u. Disabling disk!\n",
type);
sdkp->protection_type = 0;
return -ENODEV;
}

sdkp->protection_type = type;

return ret;
return 0;
}

static void sd_config_protection(struct scsi_disk *sdkp)
{
struct scsi_device *sdp = sdkp->device;

if (!sdkp->first_scan)
return;

sd_dif_config_host(sdkp);

if (!sdkp->protection_type)
return;

if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) {
sd_printk(KERN_NOTICE, sdkp,
"Disabling DIF Type %u protection\n",
sdkp->protection_type);
sdkp->protection_type = 0;
}

sd_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n",
sdkp->protection_type);
}

static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
Expand Down Expand Up @@ -3259,6 +3267,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_app_tag_own(sdkp, buffer);
sd_read_write_same(sdkp, buffer);
sd_read_security(sdkp, buffer);
sd_config_protection(sdkp);
}

/*
Expand Down Expand Up @@ -3518,11 +3527,6 @@ static int sd_probe(struct device *dev)
goto out;
}

if (sdkp->capacity)
sd_dif_config_host(sdkp);

sd_revalidate_disk(gd);

if (sdkp->security) {
sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
if (sdkp->opal_dev)
Expand Down
8 changes: 3 additions & 5 deletions drivers/scsi/sd_dif.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
bi.profile = &t10_pi_type1_crc;

bi.tuple_size = sizeof(struct t10_pi_tuple);
sd_printk(KERN_NOTICE, sdkp,
"Enabling DIX %s protection\n", bi.profile->name);

if (dif && type) {
bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE;
Expand All @@ -72,11 +70,11 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
bi.tag_size = sizeof(u16) + sizeof(u32);
else
bi.tag_size = sizeof(u16);

sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n",
bi.tag_size);
}

sd_printk(KERN_NOTICE, sdkp,
"Enabling DIX %s, application tag size %u bytes\n",
bi.profile->name, bi.tag_size);
out:
blk_integrity_register(disk, &bi);
}
Expand Down

0 comments on commit 1e02939

Please sign in to comment.