aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2014-09-26 19:19:56 -0400
committerJens Axboe <axboe@fb.com>2014-09-27 11:14:46 -0400
commit180b2f95dd331010a9930a65c8a18d6d81b94dc1 (patch)
tree8ceb4a28e15e1e588b52022a844f81daabd0f92d
parente7258c1a269e0967856c81d182c286a78f5ecf15 (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.txt10
-rw-r--r--block/bio-integrity.c19
-rw-r--r--drivers/scsi/sd_dif.c8
-rw-r--r--include/linux/bio.h11
-rw-r--r--include/linux/blk_types.h8
-rw-r--r--include/linux/blkdev.h7
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.
1294.1 BIO 1294.1 BIO
130 130
131The data integrity patches add a new field to struct bio when 131The data integrity patches add a new field to struct bio when
132CONFIG_BLK_DEV_INTEGRITY is enabled. bio->bi_integrity is a pointer 132CONFIG_BLK_DEV_INTEGRITY is enabled. bio_integrity(bio) returns a
133to a struct bip which contains the bio integrity payload. Essentially 133pointer to a struct bip which contains the bio integrity payload.
134a bip is a trimmed down struct bio which holds a bio_vec containing 134Essentially a bip is a trimmed down struct bio which holds a bio_vec
135the integrity metadata and the required housekeeping information (bvec 135containing the integrity metadata and the required housekeeping
136pool, vector count, etc.) 136information (bvec pool, vector count, etc.)
137 137
138A kernel subsystem can enable data integrity protection on a bio by 138A kernel subsystem can enable data integrity protection on a bio by
139calling bio_integrity_alloc(bio). This will allocate and attach the 139calling 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;
84err: 85err:
@@ -96,7 +97,7 @@ EXPORT_SYMBOL(bio_integrity_alloc);
96 */ 97 */
97void bio_integrity_free(struct bio *bio) 98void 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);
128int bio_integrity_add_page(struct bio *bio, struct page *page, 129int 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);
229static int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, 230static 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 */
506void bio_integrity_endio(struct bio *bio, int error) 507void 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 */
537void bio_integrity_advance(struct bio *bio, unsigned int bytes_done) 538void 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);
558void bio_integrity_trim(struct bio *bio, unsigned int offset, 559void 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);
577int bio_integrity_clone(struct bio *bio, struct bio *bio_src, 578int 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
297static 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
666extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); 673extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
667extern void bio_integrity_free(struct bio *); 674extern void bio_integrity_free(struct bio *);
668extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); 675extern 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
1517static inline int blk_integrity_rq(struct request *rq) 1517static 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
1525static inline void blk_queue_max_integrity_segments(struct request_queue *q, 1522static inline void blk_queue_max_integrity_segments(struct request_queue *q,