@@ -492,6 +492,8 @@ bool bio_integrity_prep(struct bio *bio)
bip->bip_flags |= BIP_CHECK_GUARD;
if (bi->flags & BLK_INTEGRITY_REF_TAG)
bip->bip_flags |= BIP_CHECK_REFTAG;
+ if (bi->flags & BLK_INTEGRITY_APP_TAG)
+ bip->bip_flags |= BIP_CHECK_APPTAG;
if (bio_integrity_add_page(bio, virt_to_page(buf), len,
offset_in_page(buf)) < len) {
printk(KERN_ERR "could not attach integrity payload\n");
@@ -803,6 +803,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)
{
@@ -815,14 +832,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;
}
@@ -1374,6 +1393,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
@@ -50,7 +50,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp, struct queue_limits *lim)
bi->csum_type = BLK_INTEGRITY_CSUM_CRC;
if (type != T10_PI_TYPE3_PROTECTION)
- bi->flags |= BLK_INTEGRITY_REF_TAG;
+ bi->flags |= BLK_INTEGRITY_REF_TAG | BLK_INTEGRITY_APP_TAG;
bi->tuple_size = sizeof(struct t10_pi_tuple);
@@ -13,6 +13,7 @@ enum blk_integrity_flags {
BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2,
BLK_INTEGRITY_REF_TAG = 1 << 3,
BLK_INTEGRITY_STACKED = 1 << 4,
+ BLK_INTEGRITY_APP_TAG = 1 << 5,
};
const char *blk_integrity_profile_name(struct blk_integrity *bi);
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. Introduce BLK_INTEGRITY_APP_TAG to specify apptag. This provides a way for upper layers to specify apptag checking. Signed-off-by: Anuj Gupta <anuj20.g@samsung.com> --- block/bio-integrity.c | 2 ++ drivers/scsi/sd.c | 25 +++++++++++++++++++++++-- drivers/scsi/sd_dif.c | 2 +- include/linux/blk-integrity.h | 1 + 4 files changed, 27 insertions(+), 3 deletions(-)