Message ID | 20241016112912.63542-12-anuj20.g@samsung.com |
---|---|
State | New |
Headers | show |
Series | Read/Write with meta/integrity | expand |
On Wed, Oct 16, 2024 at 04:59:12PM +0530, Anuj Gupta wrote: > Add support for sending user-meta buffer. Set tags to be checked > using flags specified by user/block-layer user and underlying DIF/DIX > configuration. The patch itself looks good: Reviewed-by: Christoph Hellwig <hch@lst.de> again this should move to before the user is added. But we still seem to lack an interface to tell the userspace application what flags are actually supported. Just failing the I/O down in the sd driver still feels suboptimal.
> +/* > + * Can't check reftag alone or apptag alone > + */ > +static bool sd_prot_flags_valid(struct scsi_cmnd *scmd) > +{ > + struct request *rq = scsi_cmd_to_rq(scmd); > + struct bio *bio = rq->bio; > + > + if (bio_integrity_flagged(bio, BIP_CHECK_REFTAG) && > + !bio_integrity_flagged(bio, BIP_CHECK_APPTAG)) > + return false; > + if (!bio_integrity_flagged(bio, BIP_CHECK_REFTAG) && > + bio_integrity_flagged(bio, BIP_CHECK_APPTAG)) > + return false; > + return true; > +} > + Martin, Christoph, and all, This snippet prevents a scenario where a apptag check is specified without a reftag check and vice-versa, which is not possible for scsi[1]. But for block layer generated integrity apptag check (BIP_CHECK_APPTAG) is not specified. When scsi drive is formatted with type1/2 PI, block layer would specify refcheck but not appcheck. Hence, these I/O's would fail. Do you see how we can handle this? [1] https://lore.kernel.org/linux-block/yq1ttgz5l6d.fsf@ca-mkp.ca.oracle.com/
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ca4bc0ac76ad..87ae19c9b29c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -802,6 +802,23 @@ static unsigned int sd_prot_flag_mask(unsigned int prot_op) return flag_mask[prot_op]; } +/* + * Can't check reftag alone or apptag alone + */ +static bool sd_prot_flags_valid(struct scsi_cmnd *scmd) +{ + struct request *rq = scsi_cmd_to_rq(scmd); + struct bio *bio = rq->bio; + + if (bio_integrity_flagged(bio, BIP_CHECK_REFTAG) && + !bio_integrity_flagged(bio, BIP_CHECK_APPTAG)) + return false; + if (!bio_integrity_flagged(bio, BIP_CHECK_REFTAG) && + bio_integrity_flagged(bio, BIP_CHECK_APPTAG)) + return false; + return true; +} + static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, unsigned int dix, unsigned int dif) { @@ -814,14 +831,16 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM)) scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM; - if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false) + if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false && + (bio_integrity_flagged(bio, BIP_CHECK_GUARD))) scmd->prot_flags |= SCSI_PROT_GUARD_CHECK; } if (dif != T10_PI_TYPE3_PROTECTION) { /* DIX/DIF Type 0, 1, 2 */ scmd->prot_flags |= SCSI_PROT_REF_INCREMENT; - if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false) + if ((bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false) && + (!dix || bio_integrity_flagged(bio, BIP_CHECK_REFTAG))) scmd->prot_flags |= SCSI_PROT_REF_CHECK; } @@ -1373,6 +1392,8 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type); dld = sd_cdl_dld(sdkp, cmd); + if (!sd_prot_flags_valid(cmd)) + goto fail; if (dif || dix) protect = sd_setup_protect_cmnd(cmd, dix, dif); else
Add support for sending user-meta buffer. Set tags to be checked using flags specified by user/block-layer user and underlying DIF/DIX configuration. Signed-off-by: Anuj Gupta <anuj20.g@samsung.com> --- drivers/scsi/sd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)