diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2014-09-26 19:19:56 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-09-27 11:14:46 -0400 |
commit | 180b2f95dd331010a9930a65c8a18d6d81b94dc1 (patch) | |
tree | 8ceb4a28e15e1e588b52022a844f81daabd0f92d | |
parent | e7258c1a269e0967856c81d182c286a78f5ecf15 (diff) |
block: Replace bi_integrity with bi_special
For commands like REQ_COPY we need a way to pass extra information along
with each bio. Like integrity metadata this information must be
available at the bottom of the stack so bi_private does not suffice.
Rename the existing bi_integrity field to bi_special and make it a union
so we can have different bio extensions for each class of command.
We previously used bi_integrity != NULL as a way to identify whether a
bio had integrity metadata or not. Introduce a REQ_INTEGRITY to be the
indicator now that bi_special can contain different things.
In addition, bio_integrity(bio) will now return a pointer to the
integrity payload (when applicable).
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | Documentation/block/data-integrity.txt | 10 | ||||
-rw-r--r-- | block/bio-integrity.c | 19 | ||||
-rw-r--r-- | drivers/scsi/sd_dif.c | 8 | ||||
-rw-r--r-- | include/linux/bio.h | 11 | ||||
-rw-r--r-- | include/linux/blk_types.h | 8 | ||||
-rw-r--r-- | include/linux/blkdev.h | 7 |
6 files changed, 36 insertions, 27 deletions
diff --git a/Documentation/block/data-integrity.txt b/Documentation/block/data-integrity.txt index b4eacf48053c..4d4de8b09530 100644 --- a/Documentation/block/data-integrity.txt +++ b/Documentation/block/data-integrity.txt | |||
@@ -129,11 +129,11 @@ interface for this is being worked on. | |||
129 | 4.1 BIO | 129 | 4.1 BIO |
130 | 130 | ||
131 | The data integrity patches add a new field to struct bio when | 131 | The data integrity patches add a new field to struct bio when |
132 | CONFIG_BLK_DEV_INTEGRITY is enabled. bio->bi_integrity is a pointer | 132 | CONFIG_BLK_DEV_INTEGRITY is enabled. bio_integrity(bio) returns a |
133 | to a struct bip which contains the bio integrity payload. Essentially | 133 | pointer to a struct bip which contains the bio integrity payload. |
134 | a bip is a trimmed down struct bio which holds a bio_vec containing | 134 | Essentially a bip is a trimmed down struct bio which holds a bio_vec |
135 | the integrity metadata and the required housekeeping information (bvec | 135 | containing the integrity metadata and the required housekeeping |
136 | pool, vector count, etc.) | 136 | information (bvec pool, vector count, etc.) |
137 | 137 | ||
138 | A kernel subsystem can enable data integrity protection on a bio by | 138 | A kernel subsystem can enable data integrity protection on a bio by |
139 | calling bio_integrity_alloc(bio). This will allocate and attach the | 139 | calling bio_integrity_alloc(bio). This will allocate and attach the |
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 36b788552c3e..bd3125c3c124 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c | |||
@@ -79,6 +79,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, | |||
79 | bip->bip_slab = idx; | 79 | bip->bip_slab = idx; |
80 | bip->bip_bio = bio; | 80 | bip->bip_bio = bio; |
81 | bio->bi_integrity = bip; | 81 | bio->bi_integrity = bip; |
82 | bio->bi_rw |= REQ_INTEGRITY; | ||
82 | 83 | ||
83 | return bip; | 84 | return bip; |
84 | err: | 85 | err: |
@@ -96,7 +97,7 @@ EXPORT_SYMBOL(bio_integrity_alloc); | |||
96 | */ | 97 | */ |
97 | void bio_integrity_free(struct bio *bio) | 98 | void bio_integrity_free(struct bio *bio) |
98 | { | 99 | { |
99 | struct bio_integrity_payload *bip = bio->bi_integrity; | 100 | struct bio_integrity_payload *bip = bio_integrity(bio); |
100 | struct bio_set *bs = bio->bi_pool; | 101 | struct bio_set *bs = bio->bi_pool; |
101 | 102 | ||
102 | if (bip->bip_owns_buf) | 103 | if (bip->bip_owns_buf) |
@@ -128,7 +129,7 @@ EXPORT_SYMBOL(bio_integrity_free); | |||
128 | int bio_integrity_add_page(struct bio *bio, struct page *page, | 129 | int bio_integrity_add_page(struct bio *bio, struct page *page, |
129 | unsigned int len, unsigned int offset) | 130 | unsigned int len, unsigned int offset) |
130 | { | 131 | { |
131 | struct bio_integrity_payload *bip = bio->bi_integrity; | 132 | struct bio_integrity_payload *bip = bio_integrity(bio); |
132 | struct bio_vec *iv; | 133 | struct bio_vec *iv; |
133 | 134 | ||
134 | if (bip->bip_vcnt >= bip->bip_max_vcnt) { | 135 | if (bip->bip_vcnt >= bip->bip_max_vcnt) { |
@@ -229,7 +230,7 @@ EXPORT_SYMBOL(bio_integrity_tag_size); | |||
229 | static int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, | 230 | static int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, |
230 | int set) | 231 | int set) |
231 | { | 232 | { |
232 | struct bio_integrity_payload *bip = bio->bi_integrity; | 233 | struct bio_integrity_payload *bip = bio_integrity(bio); |
233 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 234 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
234 | unsigned int nr_sectors; | 235 | unsigned int nr_sectors; |
235 | 236 | ||
@@ -304,12 +305,12 @@ static int bio_integrity_generate_verify(struct bio *bio, int operate) | |||
304 | struct bio_vec *bv; | 305 | struct bio_vec *bv; |
305 | sector_t sector; | 306 | sector_t sector; |
306 | unsigned int sectors, ret = 0, i; | 307 | unsigned int sectors, ret = 0, i; |
307 | void *prot_buf = bio->bi_integrity->bip_buf; | 308 | void *prot_buf = bio_integrity(bio)->bip_buf; |
308 | 309 | ||
309 | if (operate) | 310 | if (operate) |
310 | sector = bio->bi_iter.bi_sector; | 311 | sector = bio->bi_iter.bi_sector; |
311 | else | 312 | else |
312 | sector = bio->bi_integrity->bip_iter.bi_sector; | 313 | sector = bio_integrity(bio)->bip_iter.bi_sector; |
313 | 314 | ||
314 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; | 315 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; |
315 | bix.sector_size = bi->sector_size; | 316 | bix.sector_size = bi->sector_size; |
@@ -505,7 +506,7 @@ static void bio_integrity_verify_fn(struct work_struct *work) | |||
505 | */ | 506 | */ |
506 | void bio_integrity_endio(struct bio *bio, int error) | 507 | void bio_integrity_endio(struct bio *bio, int error) |
507 | { | 508 | { |
508 | struct bio_integrity_payload *bip = bio->bi_integrity; | 509 | struct bio_integrity_payload *bip = bio_integrity(bio); |
509 | 510 | ||
510 | BUG_ON(bip->bip_bio != bio); | 511 | BUG_ON(bip->bip_bio != bio); |
511 | 512 | ||
@@ -536,7 +537,7 @@ EXPORT_SYMBOL(bio_integrity_endio); | |||
536 | */ | 537 | */ |
537 | void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) | 538 | void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) |
538 | { | 539 | { |
539 | struct bio_integrity_payload *bip = bio->bi_integrity; | 540 | struct bio_integrity_payload *bip = bio_integrity(bio); |
540 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 541 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
541 | unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); | 542 | unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9); |
542 | 543 | ||
@@ -558,7 +559,7 @@ EXPORT_SYMBOL(bio_integrity_advance); | |||
558 | void bio_integrity_trim(struct bio *bio, unsigned int offset, | 559 | void bio_integrity_trim(struct bio *bio, unsigned int offset, |
559 | unsigned int sectors) | 560 | unsigned int sectors) |
560 | { | 561 | { |
561 | struct bio_integrity_payload *bip = bio->bi_integrity; | 562 | struct bio_integrity_payload *bip = bio_integrity(bio); |
562 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 563 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
563 | 564 | ||
564 | bio_integrity_advance(bio, offset << 9); | 565 | bio_integrity_advance(bio, offset << 9); |
@@ -577,7 +578,7 @@ EXPORT_SYMBOL(bio_integrity_trim); | |||
577 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, | 578 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, |
578 | gfp_t gfp_mask) | 579 | gfp_t gfp_mask) |
579 | { | 580 | { |
580 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; | 581 | struct bio_integrity_payload *bip_src = bio_integrity(bio_src); |
581 | struct bio_integrity_payload *bip; | 582 | struct bio_integrity_payload *bip; |
582 | 583 | ||
583 | BUG_ON(bip_src == NULL); | 584 | BUG_ON(bip_src == NULL); |
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index a7a691d0af7d..29f0477a8708 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c | |||
@@ -383,9 +383,9 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector, | |||
383 | if (bio_flagged(bio, BIO_MAPPED_INTEGRITY)) | 383 | if (bio_flagged(bio, BIO_MAPPED_INTEGRITY)) |
384 | break; | 384 | break; |
385 | 385 | ||
386 | virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff; | 386 | virt = bio_integrity(bio)->bip_iter.bi_sector & 0xffffffff; |
387 | 387 | ||
388 | bip_for_each_vec(iv, bio->bi_integrity, iter) { | 388 | bip_for_each_vec(iv, bio_integrity(bio), iter) { |
389 | sdt = kmap_atomic(iv.bv_page) | 389 | sdt = kmap_atomic(iv.bv_page) |
390 | + iv.bv_offset; | 390 | + iv.bv_offset; |
391 | 391 | ||
@@ -434,9 +434,9 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes) | |||
434 | struct bio_vec iv; | 434 | struct bio_vec iv; |
435 | struct bvec_iter iter; | 435 | struct bvec_iter iter; |
436 | 436 | ||
437 | virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff; | 437 | virt = bio_integrity(bio)->bip_iter.bi_sector & 0xffffffff; |
438 | 438 | ||
439 | bip_for_each_vec(iv, bio->bi_integrity, iter) { | 439 | bip_for_each_vec(iv, bio_integrity(bio), iter) { |
440 | sdt = kmap_atomic(iv.bv_page) | 440 | sdt = kmap_atomic(iv.bv_page) |
441 | + iv.bv_offset; | 441 | + iv.bv_offset; |
442 | 442 | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index 63e399b4fde5..a810a74071b2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -293,6 +293,15 @@ static inline unsigned bio_segments(struct bio *bio) | |||
293 | #define bio_get(bio) atomic_inc(&(bio)->bi_cnt) | 293 | #define bio_get(bio) atomic_inc(&(bio)->bi_cnt) |
294 | 294 | ||
295 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | 295 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
296 | |||
297 | static inline struct bio_integrity_payload *bio_integrity(struct bio *bio) | ||
298 | { | ||
299 | if (bio->bi_rw & REQ_INTEGRITY) | ||
300 | return bio->bi_integrity; | ||
301 | |||
302 | return NULL; | ||
303 | } | ||
304 | |||
296 | /* | 305 | /* |
297 | * bio integrity payload | 306 | * bio integrity payload |
298 | */ | 307 | */ |
@@ -661,8 +670,6 @@ struct biovec_slab { | |||
661 | for_each_bio(_bio) \ | 670 | for_each_bio(_bio) \ |
662 | bip_for_each_vec(_bvl, _bio->bi_integrity, _iter) | 671 | bip_for_each_vec(_bvl, _bio->bi_integrity, _iter) |
663 | 672 | ||
664 | #define bio_integrity(bio) (bio->bi_integrity != NULL) | ||
665 | |||
666 | extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); | 673 | extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); |
667 | extern void bio_integrity_free(struct bio *); | 674 | extern void bio_integrity_free(struct bio *); |
668 | extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); | 675 | extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index bb7d66460e7a..6a5d2f2de1b9 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
@@ -78,9 +78,11 @@ struct bio { | |||
78 | struct io_context *bi_ioc; | 78 | struct io_context *bi_ioc; |
79 | struct cgroup_subsys_state *bi_css; | 79 | struct cgroup_subsys_state *bi_css; |
80 | #endif | 80 | #endif |
81 | union { | ||
81 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | 82 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
82 | struct bio_integrity_payload *bi_integrity; /* data integrity */ | 83 | struct bio_integrity_payload *bi_integrity; /* data integrity */ |
83 | #endif | 84 | #endif |
85 | }; | ||
84 | 86 | ||
85 | unsigned short bi_vcnt; /* how many bio_vec's */ | 87 | unsigned short bi_vcnt; /* how many bio_vec's */ |
86 | 88 | ||
@@ -162,6 +164,7 @@ enum rq_flag_bits { | |||
162 | __REQ_WRITE_SAME, /* write same block many times */ | 164 | __REQ_WRITE_SAME, /* write same block many times */ |
163 | 165 | ||
164 | __REQ_NOIDLE, /* don't anticipate more IO after this one */ | 166 | __REQ_NOIDLE, /* don't anticipate more IO after this one */ |
167 | __REQ_INTEGRITY, /* I/O includes block integrity payload */ | ||
165 | __REQ_FUA, /* forced unit access */ | 168 | __REQ_FUA, /* forced unit access */ |
166 | __REQ_FLUSH, /* request for cache flush */ | 169 | __REQ_FLUSH, /* request for cache flush */ |
167 | 170 | ||
@@ -203,13 +206,14 @@ enum rq_flag_bits { | |||
203 | #define REQ_DISCARD (1ULL << __REQ_DISCARD) | 206 | #define REQ_DISCARD (1ULL << __REQ_DISCARD) |
204 | #define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME) | 207 | #define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME) |
205 | #define REQ_NOIDLE (1ULL << __REQ_NOIDLE) | 208 | #define REQ_NOIDLE (1ULL << __REQ_NOIDLE) |
209 | #define REQ_INTEGRITY (1ULL << __REQ_INTEGRITY) | ||
206 | 210 | ||
207 | #define REQ_FAILFAST_MASK \ | 211 | #define REQ_FAILFAST_MASK \ |
208 | (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) | 212 | (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) |
209 | #define REQ_COMMON_MASK \ | 213 | #define REQ_COMMON_MASK \ |
210 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ | 214 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ |
211 | REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ | 215 | REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ |
212 | REQ_SECURE) | 216 | REQ_SECURE | REQ_INTEGRITY) |
213 | #define REQ_CLONE_MASK REQ_COMMON_MASK | 217 | #define REQ_CLONE_MASK REQ_COMMON_MASK |
214 | 218 | ||
215 | #define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) | 219 | #define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 49f3461e4272..7fcb2caef559 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1514,12 +1514,9 @@ static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) | |||
1514 | return disk->integrity; | 1514 | return disk->integrity; |
1515 | } | 1515 | } |
1516 | 1516 | ||
1517 | static inline int blk_integrity_rq(struct request *rq) | 1517 | static inline bool blk_integrity_rq(struct request *rq) |
1518 | { | 1518 | { |
1519 | if (rq->bio == NULL) | 1519 | return rq->cmd_flags & REQ_INTEGRITY; |
1520 | return 0; | ||
1521 | |||
1522 | return bio_integrity(rq->bio); | ||
1523 | } | 1520 | } |
1524 | 1521 | ||
1525 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, | 1522 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, |