aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-integrity.c40
-rw-r--r--drivers/scsi/sd_dif.c30
-rw-r--r--fs/bio-integrity.c108
-rw-r--r--include/linux/bio.h19
4 files changed, 71 insertions, 126 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 03cf7179e8ef..7fbab84399e6 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -43,30 +43,32 @@ static const char *bi_unsupported_name = "unsupported";
43 */ 43 */
44int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio) 44int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio)
45{ 45{
46 struct bio_vec *iv, *ivprv = NULL; 46 struct bio_vec iv, ivprv = { NULL };
47 unsigned int segments = 0; 47 unsigned int segments = 0;
48 unsigned int seg_size = 0; 48 unsigned int seg_size = 0;
49 unsigned int i = 0; 49 struct bvec_iter iter;
50 int prev = 0;
50 51
51 bio_for_each_integrity_vec(iv, bio, i) { 52 bio_for_each_integrity_vec(iv, bio, iter) {
52 53
53 if (ivprv) { 54 if (prev) {
54 if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv)) 55 if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv))
55 goto new_segment; 56 goto new_segment;
56 57
57 if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv)) 58 if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv))
58 goto new_segment; 59 goto new_segment;
59 60
60 if (seg_size + iv->bv_len > queue_max_segment_size(q)) 61 if (seg_size + iv.bv_len > queue_max_segment_size(q))
61 goto new_segment; 62 goto new_segment;
62 63
63 seg_size += iv->bv_len; 64 seg_size += iv.bv_len;
64 } else { 65 } else {
65new_segment: 66new_segment:
66 segments++; 67 segments++;
67 seg_size = iv->bv_len; 68 seg_size = iv.bv_len;
68 } 69 }
69 70
71 prev = 1;
70 ivprv = iv; 72 ivprv = iv;
71 } 73 }
72 74
@@ -87,24 +89,25 @@ EXPORT_SYMBOL(blk_rq_count_integrity_sg);
87int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio, 89int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
88 struct scatterlist *sglist) 90 struct scatterlist *sglist)
89{ 91{
90 struct bio_vec *iv, *ivprv = NULL; 92 struct bio_vec iv, ivprv = { NULL };
91 struct scatterlist *sg = NULL; 93 struct scatterlist *sg = NULL;
92 unsigned int segments = 0; 94 unsigned int segments = 0;
93 unsigned int i = 0; 95 struct bvec_iter iter;
96 int prev = 0;
94 97
95 bio_for_each_integrity_vec(iv, bio, i) { 98 bio_for_each_integrity_vec(iv, bio, iter) {
96 99
97 if (ivprv) { 100 if (prev) {
98 if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv)) 101 if (!BIOVEC_PHYS_MERGEABLE(&ivprv, &iv))
99 goto new_segment; 102 goto new_segment;
100 103
101 if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv)) 104 if (!BIOVEC_SEG_BOUNDARY(q, &ivprv, &iv))
102 goto new_segment; 105 goto new_segment;
103 106
104 if (sg->length + iv->bv_len > queue_max_segment_size(q)) 107 if (sg->length + iv.bv_len > queue_max_segment_size(q))
105 goto new_segment; 108 goto new_segment;
106 109
107 sg->length += iv->bv_len; 110 sg->length += iv.bv_len;
108 } else { 111 } else {
109new_segment: 112new_segment:
110 if (!sg) 113 if (!sg)
@@ -114,10 +117,11 @@ new_segment:
114 sg = sg_next(sg); 117 sg = sg_next(sg);
115 } 118 }
116 119
117 sg_set_page(sg, iv->bv_page, iv->bv_len, iv->bv_offset); 120 sg_set_page(sg, iv.bv_page, iv.bv_len, iv.bv_offset);
118 segments++; 121 segments++;
119 } 122 }
120 123
124 prev = 1;
121 ivprv = iv; 125 ivprv = iv;
122 } 126 }
123 127
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 6174ca4ea275..a7a691d0af7d 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -365,7 +365,6 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector,
365 struct bio *bio; 365 struct bio *bio;
366 struct scsi_disk *sdkp; 366 struct scsi_disk *sdkp;
367 struct sd_dif_tuple *sdt; 367 struct sd_dif_tuple *sdt;
368 unsigned int i, j;
369 u32 phys, virt; 368 u32 phys, virt;
370 369
371 sdkp = rq->bio->bi_bdev->bd_disk->private_data; 370 sdkp = rq->bio->bi_bdev->bd_disk->private_data;
@@ -376,19 +375,21 @@ void sd_dif_prepare(struct request *rq, sector_t hw_sector,
376 phys = hw_sector & 0xffffffff; 375 phys = hw_sector & 0xffffffff;
377 376
378 __rq_for_each_bio(bio, rq) { 377 __rq_for_each_bio(bio, rq) {
379 struct bio_vec *iv; 378 struct bio_vec iv;
379 struct bvec_iter iter;
380 unsigned int j;
380 381
381 /* Already remapped? */ 382 /* Already remapped? */
382 if (bio_flagged(bio, BIO_MAPPED_INTEGRITY)) 383 if (bio_flagged(bio, BIO_MAPPED_INTEGRITY))
383 break; 384 break;
384 385
385 virt = bio->bi_integrity->bip_sector & 0xffffffff; 386 virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff;
386 387
387 bip_for_each_vec(iv, bio->bi_integrity, i) { 388 bip_for_each_vec(iv, bio->bi_integrity, iter) {
388 sdt = kmap_atomic(iv->bv_page) 389 sdt = kmap_atomic(iv.bv_page)
389 + iv->bv_offset; 390 + iv.bv_offset;
390 391
391 for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { 392 for (j = 0; j < iv.bv_len; j += tuple_sz, sdt++) {
392 393
393 if (be32_to_cpu(sdt->ref_tag) == virt) 394 if (be32_to_cpu(sdt->ref_tag) == virt)
394 sdt->ref_tag = cpu_to_be32(phys); 395 sdt->ref_tag = cpu_to_be32(phys);
@@ -414,7 +415,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
414 struct scsi_disk *sdkp; 415 struct scsi_disk *sdkp;
415 struct bio *bio; 416 struct bio *bio;
416 struct sd_dif_tuple *sdt; 417 struct sd_dif_tuple *sdt;
417 unsigned int i, j, sectors, sector_sz; 418 unsigned int j, sectors, sector_sz;
418 u32 phys, virt; 419 u32 phys, virt;
419 420
420 sdkp = scsi_disk(scmd->request->rq_disk); 421 sdkp = scsi_disk(scmd->request->rq_disk);
@@ -430,15 +431,16 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
430 phys >>= 3; 431 phys >>= 3;
431 432
432 __rq_for_each_bio(bio, scmd->request) { 433 __rq_for_each_bio(bio, scmd->request) {
433 struct bio_vec *iv; 434 struct bio_vec iv;
435 struct bvec_iter iter;
434 436
435 virt = bio->bi_integrity->bip_sector & 0xffffffff; 437 virt = bio->bi_integrity->bip_iter.bi_sector & 0xffffffff;
436 438
437 bip_for_each_vec(iv, bio->bi_integrity, i) { 439 bip_for_each_vec(iv, bio->bi_integrity, iter) {
438 sdt = kmap_atomic(iv->bv_page) 440 sdt = kmap_atomic(iv.bv_page)
439 + iv->bv_offset; 441 + iv.bv_offset;
440 442
441 for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) { 443 for (j = 0; j < iv.bv_len; j += tuple_sz, sdt++) {
442 444
443 if (sectors == 0) { 445 if (sectors == 0) {
444 kunmap_atomic(sdt); 446 kunmap_atomic(sdt);
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index 9127db86f315..fed744b8c9e5 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -134,8 +134,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
134 return 0; 134 return 0;
135 } 135 }
136 136
137 iv = bip_vec_idx(bip, bip->bip_vcnt); 137 iv = bip->bip_vec + bip->bip_vcnt;
138 BUG_ON(iv == NULL);
139 138
140 iv->bv_page = page; 139 iv->bv_page = page;
141 iv->bv_len = len; 140 iv->bv_len = len;
@@ -203,6 +202,12 @@ static inline unsigned int bio_integrity_hw_sectors(struct blk_integrity *bi,
203 return sectors; 202 return sectors;
204} 203}
205 204
205static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
206 unsigned int sectors)
207{
208 return bio_integrity_hw_sectors(bi, sectors) * bi->tuple_size;
209}
210
206/** 211/**
207 * bio_integrity_tag_size - Retrieve integrity tag space 212 * bio_integrity_tag_size - Retrieve integrity tag space
208 * @bio: bio to inspect 213 * @bio: bio to inspect
@@ -235,9 +240,9 @@ int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, int set)
235 nr_sectors = bio_integrity_hw_sectors(bi, 240 nr_sectors = bio_integrity_hw_sectors(bi,
236 DIV_ROUND_UP(len, bi->tag_size)); 241 DIV_ROUND_UP(len, bi->tag_size));
237 242
238 if (nr_sectors * bi->tuple_size > bip->bip_size) { 243 if (nr_sectors * bi->tuple_size > bip->bip_iter.bi_size) {
239 printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", 244 printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", __func__,
240 __func__, nr_sectors * bi->tuple_size, bip->bip_size); 245 nr_sectors * bi->tuple_size, bip->bip_iter.bi_size);
241 return -1; 246 return -1;
242 } 247 }
243 248
@@ -322,7 +327,7 @@ static void bio_integrity_generate(struct bio *bio)
322 sector += sectors; 327 sector += sectors;
323 prot_buf += sectors * bi->tuple_size; 328 prot_buf += sectors * bi->tuple_size;
324 total += sectors * bi->tuple_size; 329 total += sectors * bi->tuple_size;
325 BUG_ON(total > bio->bi_integrity->bip_size); 330 BUG_ON(total > bio->bi_integrity->bip_iter.bi_size);
326 331
327 kunmap_atomic(kaddr); 332 kunmap_atomic(kaddr);
328 } 333 }
@@ -387,8 +392,8 @@ int bio_integrity_prep(struct bio *bio)
387 392
388 bip->bip_owns_buf = 1; 393 bip->bip_owns_buf = 1;
389 bip->bip_buf = buf; 394 bip->bip_buf = buf;
390 bip->bip_size = len; 395 bip->bip_iter.bi_size = len;
391 bip->bip_sector = bio->bi_iter.bi_sector; 396 bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
392 397
393 /* Map it */ 398 /* Map it */
394 offset = offset_in_page(buf); 399 offset = offset_in_page(buf);
@@ -444,7 +449,7 @@ static int bio_integrity_verify(struct bio *bio)
444 struct blk_integrity_exchg bix; 449 struct blk_integrity_exchg bix;
445 struct bio_vec bv; 450 struct bio_vec bv;
446 struct bvec_iter iter; 451 struct bvec_iter iter;
447 sector_t sector = bio->bi_integrity->bip_sector; 452 sector_t sector = bio->bi_integrity->bip_iter.bi_sector;
448 unsigned int sectors, total, ret; 453 unsigned int sectors, total, ret;
449 void *prot_buf = bio->bi_integrity->bip_buf; 454 void *prot_buf = bio->bi_integrity->bip_buf;
450 455
@@ -470,7 +475,7 @@ static int bio_integrity_verify(struct bio *bio)
470 sector += sectors; 475 sector += sectors;
471 prot_buf += sectors * bi->tuple_size; 476 prot_buf += sectors * bi->tuple_size;
472 total += sectors * bi->tuple_size; 477 total += sectors * bi->tuple_size;
473 BUG_ON(total > bio->bi_integrity->bip_size); 478 BUG_ON(total > bio->bi_integrity->bip_iter.bi_size);
474 479
475 kunmap_atomic(kaddr); 480 kunmap_atomic(kaddr);
476 } 481 }
@@ -535,56 +540,6 @@ void bio_integrity_endio(struct bio *bio, int error)
535EXPORT_SYMBOL(bio_integrity_endio); 540EXPORT_SYMBOL(bio_integrity_endio);
536 541
537/** 542/**
538 * bio_integrity_mark_head - Advance bip_vec skip bytes
539 * @bip: Integrity vector to advance
540 * @skip: Number of bytes to advance it
541 */
542void bio_integrity_mark_head(struct bio_integrity_payload *bip,
543 unsigned int skip)
544{
545 struct bio_vec *iv;
546 unsigned int i;
547
548 bip_for_each_vec(iv, bip, i) {
549 if (skip == 0) {
550 bip->bip_idx = i;
551 return;
552 } else if (skip >= iv->bv_len) {
553 skip -= iv->bv_len;
554 } else { /* skip < iv->bv_len) */
555 iv->bv_offset += skip;
556 iv->bv_len -= skip;
557 bip->bip_idx = i;
558 return;
559 }
560 }
561}
562
563/**
564 * bio_integrity_mark_tail - Truncate bip_vec to be len bytes long
565 * @bip: Integrity vector to truncate
566 * @len: New length of integrity vector
567 */
568void bio_integrity_mark_tail(struct bio_integrity_payload *bip,
569 unsigned int len)
570{
571 struct bio_vec *iv;
572 unsigned int i;
573
574 bip_for_each_vec(iv, bip, i) {
575 if (len == 0) {
576 bip->bip_vcnt = i;
577 return;
578 } else if (len >= iv->bv_len) {
579 len -= iv->bv_len;
580 } else { /* len < iv->bv_len) */
581 iv->bv_len = len;
582 len = 0;
583 }
584 }
585}
586
587/**
588 * bio_integrity_advance - Advance integrity vector 543 * bio_integrity_advance - Advance integrity vector
589 * @bio: bio whose integrity vector to update 544 * @bio: bio whose integrity vector to update
590 * @bytes_done: number of data bytes that have been completed 545 * @bytes_done: number of data bytes that have been completed
@@ -597,13 +552,9 @@ void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
597{ 552{
598 struct bio_integrity_payload *bip = bio->bi_integrity; 553 struct bio_integrity_payload *bip = bio->bi_integrity;
599 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); 554 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
600 unsigned int nr_sectors; 555 unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
601 556
602 BUG_ON(bip == NULL); 557 bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
603 BUG_ON(bi == NULL);
604
605 nr_sectors = bio_integrity_hw_sectors(bi, bytes_done >> 9);
606 bio_integrity_mark_head(bip, nr_sectors * bi->tuple_size);
607} 558}
608EXPORT_SYMBOL(bio_integrity_advance); 559EXPORT_SYMBOL(bio_integrity_advance);
609 560
@@ -623,16 +574,9 @@ void bio_integrity_trim(struct bio *bio, unsigned int offset,
623{ 574{
624 struct bio_integrity_payload *bip = bio->bi_integrity; 575 struct bio_integrity_payload *bip = bio->bi_integrity;
625 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); 576 struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
626 unsigned int nr_sectors;
627 577
628 BUG_ON(bip == NULL); 578 bio_integrity_advance(bio, offset << 9);
629 BUG_ON(bi == NULL); 579 bip->bip_iter.bi_size = bio_integrity_bytes(bi, sectors);
630 BUG_ON(!bio_flagged(bio, BIO_CLONED));
631
632 nr_sectors = bio_integrity_hw_sectors(bi, sectors);
633 bip->bip_sector = bip->bip_sector + offset;
634 bio_integrity_mark_head(bip, offset * bi->tuple_size);
635 bio_integrity_mark_tail(bip, sectors * bi->tuple_size);
636} 580}
637EXPORT_SYMBOL(bio_integrity_trim); 581EXPORT_SYMBOL(bio_integrity_trim);
638 582
@@ -662,8 +606,8 @@ void bio_integrity_split(struct bio *bio, struct bio_pair *bp, int sectors)
662 bp->bio1.bi_integrity = &bp->bip1; 606 bp->bio1.bi_integrity = &bp->bip1;
663 bp->bio2.bi_integrity = &bp->bip2; 607 bp->bio2.bi_integrity = &bp->bip2;
664 608
665 bp->iv1 = bip->bip_vec[bip->bip_idx]; 609 bp->iv1 = bip->bip_vec[bip->bip_iter.bi_idx];
666 bp->iv2 = bip->bip_vec[bip->bip_idx]; 610 bp->iv2 = bip->bip_vec[bip->bip_iter.bi_idx];
667 611
668 bp->bip1.bip_vec = &bp->iv1; 612 bp->bip1.bip_vec = &bp->iv1;
669 bp->bip2.bip_vec = &bp->iv2; 613 bp->bip2.bip_vec = &bp->iv2;
@@ -672,11 +616,12 @@ void bio_integrity_split(struct bio *bio, struct bio_pair *bp, int sectors)
672 bp->iv2.bv_offset += sectors * bi->tuple_size; 616 bp->iv2.bv_offset += sectors * bi->tuple_size;
673 bp->iv2.bv_len -= sectors * bi->tuple_size; 617 bp->iv2.bv_len -= sectors * bi->tuple_size;
674 618
675 bp->bip1.bip_sector = bio->bi_integrity->bip_sector; 619 bp->bip1.bip_iter.bi_sector = bio->bi_integrity->bip_iter.bi_sector;
676 bp->bip2.bip_sector = bio->bi_integrity->bip_sector + nr_sectors; 620 bp->bip2.bip_iter.bi_sector =
621 bio->bi_integrity->bip_iter.bi_sector + nr_sectors;
677 622
678 bp->bip1.bip_vcnt = bp->bip2.bip_vcnt = 1; 623 bp->bip1.bip_vcnt = bp->bip2.bip_vcnt = 1;
679 bp->bip1.bip_idx = bp->bip2.bip_idx = 0; 624 bp->bip1.bip_iter.bi_idx = bp->bip2.bip_iter.bi_idx = 0;
680} 625}
681EXPORT_SYMBOL(bio_integrity_split); 626EXPORT_SYMBOL(bio_integrity_split);
682 627
@@ -704,9 +649,8 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
704 memcpy(bip->bip_vec, bip_src->bip_vec, 649 memcpy(bip->bip_vec, bip_src->bip_vec,
705 bip_src->bip_vcnt * sizeof(struct bio_vec)); 650 bip_src->bip_vcnt * sizeof(struct bio_vec));
706 651
707 bip->bip_sector = bip_src->bip_sector;
708 bip->bip_vcnt = bip_src->bip_vcnt; 652 bip->bip_vcnt = bip_src->bip_vcnt;
709 bip->bip_idx = bip_src->bip_idx; 653 bip->bip_iter = bip_src->bip_iter;
710 654
711 return 0; 655 return 0;
712} 656}
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 04e592e74c92..930cb73c894b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -244,16 +244,15 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
244struct bio_integrity_payload { 244struct bio_integrity_payload {
245 struct bio *bip_bio; /* parent bio */ 245 struct bio *bip_bio; /* parent bio */
246 246
247 sector_t bip_sector; /* virtual start sector */ 247 struct bvec_iter bip_iter;
248 248
249 /* kill - should just use bip_vec */
249 void *bip_buf; /* generated integrity data */ 250 void *bip_buf; /* generated integrity data */
250 bio_end_io_t *bip_end_io; /* saved I/O completion fn */
251 251
252 unsigned int bip_size; 252 bio_end_io_t *bip_end_io; /* saved I/O completion fn */
253 253
254 unsigned short bip_slab; /* slab the bip came from */ 254 unsigned short bip_slab; /* slab the bip came from */
255 unsigned short bip_vcnt; /* # of integrity bio_vecs */ 255 unsigned short bip_vcnt; /* # of integrity bio_vecs */
256 unsigned short bip_idx; /* current bip_vec index */
257 unsigned bip_owns_buf:1; /* should free bip_buf */ 256 unsigned bip_owns_buf:1; /* should free bip_buf */
258 257
259 struct work_struct bip_work; /* I/O completion */ 258 struct work_struct bip_work; /* I/O completion */
@@ -626,16 +625,12 @@ struct biovec_slab {
626 625
627#if defined(CONFIG_BLK_DEV_INTEGRITY) 626#if defined(CONFIG_BLK_DEV_INTEGRITY)
628 627
629#define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)]))
630#define bip_vec(bip) bip_vec_idx(bip, 0)
631 628
632#define __bip_for_each_vec(bvl, bip, i, start_idx) \
633 for (bvl = bip_vec_idx((bip), (start_idx)), i = (start_idx); \
634 i < (bip)->bip_vcnt; \
635 bvl++, i++)
636 629
637#define bip_for_each_vec(bvl, bip, i) \ 630#define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)]))
638 __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) 631
632#define bip_for_each_vec(bvl, bip, iter) \
633 for_each_bvec(bvl, (bip)->bip_vec, iter, (bip)->bip_iter)
639 634
640#define bio_for_each_integrity_vec(_bvl, _bio, _iter) \ 635#define bio_for_each_integrity_vec(_bvl, _bio, _iter) \
641 for_each_bio(_bio) \ 636 for_each_bio(_bio) \