block: Make the integrity mapped property a bio flag
Martin K. Petersen [Fri, 15 Oct 2010 13:49:20 +0000 (15:49 +0200)]
Previously we tracked whether the integrity metadata had been remapped
using a request flag. This was fine for low-level retries. However, if
an I/O was redriven by upper layers we would end up remapping again,
causing the retry to fail.

Deprecate the REQ_INTEGRITY flag and introduce BIO_MAPPED_INTEGRITY
which enables filesystems to notify lower layers that the bio in
question has already been remapped.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>

drivers/scsi/sd_dif.c
include/linux/blk_types.h

index 84be621..0cb39ff 100644 (file)
@@ -375,21 +375,20 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
        unsigned int i, j;
        u32 phys, virt;
 
-       /* Already remapped? */
-       if (rq->cmd_flags & REQ_INTEGRITY)
-               return 0;
-
        sdkp = rq->bio->bi_bdev->bd_disk->private_data;
 
        if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION)
                return 0;
 
-       rq->cmd_flags |= REQ_INTEGRITY;
        phys = hw_sector & 0xffffffff;
 
        __rq_for_each_bio(bio, rq) {
                struct bio_vec *iv;
 
+               /* Already remapped? */
+               if (bio_flagged(bio, BIO_MAPPED_INTEGRITY))
+                       break;
+
                virt = bio->bi_integrity->bip_sector & 0xffffffff;
 
                bip_for_each_vec(iv, bio->bi_integrity, i) {
@@ -408,6 +407,8 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
 
                        kunmap_atomic(sdt, KM_USER0);
                }
+
+               bio->bi_flags |= BIO_MAPPED_INTEGRITY;
        }
 
        return 0;
index 10a0c29..d366296 100644 (file)
@@ -97,6 +97,7 @@ struct bio {
 #define BIO_NULL_MAPPED 9      /* contains invalid user pages */
 #define BIO_FS_INTEGRITY 10    /* fs owns integrity data, not block layer */
 #define BIO_QUIET      11      /* Make BIO Quiet */
+#define BIO_MAPPED_INTEGRITY 12/* integrity metadata has been remapped */
 #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
 
 /*
@@ -148,7 +149,6 @@ enum rq_flag_bits {
        __REQ_ORDERED_COLOR,    /* is before or after barrier */
        __REQ_ALLOCED,          /* request came from our alloc pool */
        __REQ_COPY_USER,        /* contains copies of user pages */
-       __REQ_INTEGRITY,        /* integrity metadata has been remapped */
        __REQ_FLUSH,            /* request for cache flush */
        __REQ_IO_STAT,          /* account I/O stat */
        __REQ_MIXED_MERGE,      /* merge of different types, fail separately */
@@ -190,7 +190,6 @@ enum rq_flag_bits {
 #define REQ_ORDERED_COLOR      (1 << __REQ_ORDERED_COLOR)
 #define REQ_ALLOCED            (1 << __REQ_ALLOCED)
 #define REQ_COPY_USER          (1 << __REQ_COPY_USER)
-#define REQ_INTEGRITY          (1 << __REQ_INTEGRITY)
 #define REQ_FLUSH              (1 << __REQ_FLUSH)
 #define REQ_IO_STAT            (1 << __REQ_IO_STAT)
 #define REQ_MIXED_MERGE                (1 << __REQ_MIXED_MERGE)