xref: /linux/block/bio-integrity.c (revision e7258c1a269e0967856c81d182c286a78f5ecf15)
17ba1ba12SMartin K. Petersen /*
27ba1ba12SMartin K. Petersen  * bio-integrity.c - bio data integrity extensions
37ba1ba12SMartin K. Petersen  *
47878cba9SMartin K. Petersen  * Copyright (C) 2007, 2008, 2009 Oracle Corporation
57ba1ba12SMartin K. Petersen  * Written by: Martin K. Petersen <martin.petersen@oracle.com>
67ba1ba12SMartin K. Petersen  *
77ba1ba12SMartin K. Petersen  * This program is free software; you can redistribute it and/or
87ba1ba12SMartin K. Petersen  * modify it under the terms of the GNU General Public License version
97ba1ba12SMartin K. Petersen  * 2 as published by the Free Software Foundation.
107ba1ba12SMartin K. Petersen  *
117ba1ba12SMartin K. Petersen  * This program is distributed in the hope that it will be useful, but
127ba1ba12SMartin K. Petersen  * WITHOUT ANY WARRANTY; without even the implied warranty of
137ba1ba12SMartin K. Petersen  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147ba1ba12SMartin K. Petersen  * General Public License for more details.
157ba1ba12SMartin K. Petersen  *
167ba1ba12SMartin K. Petersen  * You should have received a copy of the GNU General Public License
177ba1ba12SMartin K. Petersen  * along with this program; see the file COPYING.  If not, write to
187ba1ba12SMartin K. Petersen  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
197ba1ba12SMartin K. Petersen  * USA.
207ba1ba12SMartin K. Petersen  *
217ba1ba12SMartin K. Petersen  */
227ba1ba12SMartin K. Petersen 
237ba1ba12SMartin K. Petersen #include <linux/blkdev.h>
247ba1ba12SMartin K. Petersen #include <linux/mempool.h>
25afeacc8cSPaul Gortmaker #include <linux/export.h>
267ba1ba12SMartin K. Petersen #include <linux/bio.h>
277ba1ba12SMartin K. Petersen #include <linux/workqueue.h>
285a0e3ad6STejun Heo #include <linux/slab.h>
297ba1ba12SMartin K. Petersen 
309f060e22SKent Overstreet #define BIP_INLINE_VECS	4
317878cba9SMartin K. Petersen 
329f060e22SKent Overstreet static struct kmem_cache *bip_slab;
337ba1ba12SMartin K. Petersen static struct workqueue_struct *kintegrityd_wq;
347ba1ba12SMartin K. Petersen 
357878cba9SMartin K. Petersen /**
361e2a410fSKent Overstreet  * bio_integrity_alloc - Allocate integrity payload and attach it to bio
377878cba9SMartin K. Petersen  * @bio:	bio to attach integrity metadata to
387878cba9SMartin K. Petersen  * @gfp_mask:	Memory allocation mask
397878cba9SMartin K. Petersen  * @nr_vecs:	Number of integrity metadata scatter-gather elements
407878cba9SMartin K. Petersen  *
417878cba9SMartin K. Petersen  * Description: This function prepares a bio for attaching integrity
427878cba9SMartin K. Petersen  * metadata.  nr_vecs specifies the maximum number of pages containing
437878cba9SMartin K. Petersen  * integrity metadata that can be attached.
447878cba9SMartin K. Petersen  */
451e2a410fSKent Overstreet struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
467878cba9SMartin K. Petersen 						  gfp_t gfp_mask,
471e2a410fSKent Overstreet 						  unsigned int nr_vecs)
487878cba9SMartin K. Petersen {
497878cba9SMartin K. Petersen 	struct bio_integrity_payload *bip;
501e2a410fSKent Overstreet 	struct bio_set *bs = bio->bi_pool;
519f060e22SKent Overstreet 	unsigned long idx = BIO_POOL_NONE;
529f060e22SKent Overstreet 	unsigned inline_vecs;
531e2a410fSKent Overstreet 
549f060e22SKent Overstreet 	if (!bs) {
559f060e22SKent Overstreet 		bip = kmalloc(sizeof(struct bio_integrity_payload) +
569f060e22SKent Overstreet 			      sizeof(struct bio_vec) * nr_vecs, gfp_mask);
579f060e22SKent Overstreet 		inline_vecs = nr_vecs;
589f060e22SKent Overstreet 	} else {
597878cba9SMartin K. Petersen 		bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
609f060e22SKent Overstreet 		inline_vecs = BIP_INLINE_VECS;
619f060e22SKent Overstreet 	}
627878cba9SMartin K. Petersen 
639f060e22SKent Overstreet 	if (unlikely(!bip))
647878cba9SMartin K. Petersen 		return NULL;
657878cba9SMartin K. Petersen 
667878cba9SMartin K. Petersen 	memset(bip, 0, sizeof(*bip));
677878cba9SMartin K. Petersen 
689f060e22SKent Overstreet 	if (nr_vecs > inline_vecs) {
699f060e22SKent Overstreet 		bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx,
709f060e22SKent Overstreet 					  bs->bvec_integrity_pool);
719f060e22SKent Overstreet 		if (!bip->bip_vec)
729f060e22SKent Overstreet 			goto err;
73cbcd1054SGu Zheng 		bip->bip_max_vcnt = bvec_nr_vecs(idx);
749f060e22SKent Overstreet 	} else {
759f060e22SKent Overstreet 		bip->bip_vec = bip->bip_inline_vecs;
76cbcd1054SGu Zheng 		bip->bip_max_vcnt = inline_vecs;
779f060e22SKent Overstreet 	}
789f060e22SKent Overstreet 
797878cba9SMartin K. Petersen 	bip->bip_slab = idx;
807878cba9SMartin K. Petersen 	bip->bip_bio = bio;
817878cba9SMartin K. Petersen 	bio->bi_integrity = bip;
827878cba9SMartin K. Petersen 
837878cba9SMartin K. Petersen 	return bip;
849f060e22SKent Overstreet err:
859f060e22SKent Overstreet 	mempool_free(bip, bs->bio_integrity_pool);
869f060e22SKent Overstreet 	return NULL;
877878cba9SMartin K. Petersen }
887ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_alloc);
897ba1ba12SMartin K. Petersen 
907ba1ba12SMartin K. Petersen /**
917ba1ba12SMartin K. Petersen  * bio_integrity_free - Free bio integrity payload
927ba1ba12SMartin K. Petersen  * @bio:	bio containing bip to be freed
937ba1ba12SMartin K. Petersen  *
947ba1ba12SMartin K. Petersen  * Description: Used to free the integrity portion of a bio. Usually
957ba1ba12SMartin K. Petersen  * called from bio_free().
967ba1ba12SMartin K. Petersen  */
971e2a410fSKent Overstreet void bio_integrity_free(struct bio *bio)
987ba1ba12SMartin K. Petersen {
997ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
1001e2a410fSKent Overstreet 	struct bio_set *bs = bio->bi_pool;
1011e2a410fSKent Overstreet 
10229ed7813SKent Overstreet 	if (bip->bip_owns_buf)
1037ba1ba12SMartin K. Petersen 		kfree(bip->bip_buf);
1047ba1ba12SMartin K. Petersen 
1059f060e22SKent Overstreet 	if (bs) {
1069f060e22SKent Overstreet 		if (bip->bip_slab != BIO_POOL_NONE)
1079f060e22SKent Overstreet 			bvec_free(bs->bvec_integrity_pool, bip->bip_vec,
1089f060e22SKent Overstreet 				  bip->bip_slab);
1099f060e22SKent Overstreet 
1107878cba9SMartin K. Petersen 		mempool_free(bip, bs->bio_integrity_pool);
1119f060e22SKent Overstreet 	} else {
1129f060e22SKent Overstreet 		kfree(bip);
1139f060e22SKent Overstreet 	}
1147ba1ba12SMartin K. Petersen 
1157ba1ba12SMartin K. Petersen 	bio->bi_integrity = NULL;
1167ba1ba12SMartin K. Petersen }
1177ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_free);
1187ba1ba12SMartin K. Petersen 
1197ba1ba12SMartin K. Petersen /**
1207ba1ba12SMartin K. Petersen  * bio_integrity_add_page - Attach integrity metadata
1217ba1ba12SMartin K. Petersen  * @bio:	bio to update
1227ba1ba12SMartin K. Petersen  * @page:	page containing integrity metadata
1237ba1ba12SMartin K. Petersen  * @len:	number of bytes of integrity metadata in page
1247ba1ba12SMartin K. Petersen  * @offset:	start offset within page
1257ba1ba12SMartin K. Petersen  *
1267ba1ba12SMartin K. Petersen  * Description: Attach a page containing integrity metadata to bio.
1277ba1ba12SMartin K. Petersen  */
1287ba1ba12SMartin K. Petersen int bio_integrity_add_page(struct bio *bio, struct page *page,
1297ba1ba12SMartin K. Petersen 			   unsigned int len, unsigned int offset)
1307ba1ba12SMartin K. Petersen {
1317ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
1327ba1ba12SMartin K. Petersen 	struct bio_vec *iv;
1337ba1ba12SMartin K. Petersen 
134cbcd1054SGu Zheng 	if (bip->bip_vcnt >= bip->bip_max_vcnt) {
1357ba1ba12SMartin K. Petersen 		printk(KERN_ERR "%s: bip_vec full\n", __func__);
1367ba1ba12SMartin K. Petersen 		return 0;
1377ba1ba12SMartin K. Petersen 	}
1387ba1ba12SMartin K. Petersen 
139d57a5f7cSKent Overstreet 	iv = bip->bip_vec + bip->bip_vcnt;
1407ba1ba12SMartin K. Petersen 
1417ba1ba12SMartin K. Petersen 	iv->bv_page = page;
1427ba1ba12SMartin K. Petersen 	iv->bv_len = len;
1437ba1ba12SMartin K. Petersen 	iv->bv_offset = offset;
1447ba1ba12SMartin K. Petersen 	bip->bip_vcnt++;
1457ba1ba12SMartin K. Petersen 
1467ba1ba12SMartin K. Petersen 	return len;
1477ba1ba12SMartin K. Petersen }
1487ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_add_page);
1497ba1ba12SMartin K. Petersen 
1507ba1ba12SMartin K. Petersen /**
1517ba1ba12SMartin K. Petersen  * bio_integrity_enabled - Check whether integrity can be passed
1527ba1ba12SMartin K. Petersen  * @bio:	bio to check
1537ba1ba12SMartin K. Petersen  *
1547ba1ba12SMartin K. Petersen  * Description: Determines whether bio_integrity_prep() can be called
1557ba1ba12SMartin K. Petersen  * on this bio or not.	bio data direction and target device must be
1567ba1ba12SMartin K. Petersen  * set prior to calling.  The functions honors the write_generate and
1577ba1ba12SMartin K. Petersen  * read_verify flags in sysfs.
1587ba1ba12SMartin K. Petersen  */
159*e7258c1aSMartin K. Petersen bool bio_integrity_enabled(struct bio *bio)
1607ba1ba12SMartin K. Petersen {
161*e7258c1aSMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
162*e7258c1aSMartin K. Petersen 
163e69f18f0SMartin K. Petersen 	if (!bio_is_rw(bio))
164*e7258c1aSMartin K. Petersen 		return false;
165e69f18f0SMartin K. Petersen 
1667ba1ba12SMartin K. Petersen 	/* Already protected? */
1677ba1ba12SMartin K. Petersen 	if (bio_integrity(bio))
168*e7258c1aSMartin K. Petersen 		return false;
1697ba1ba12SMartin K. Petersen 
170*e7258c1aSMartin K. Petersen 	if (bi == NULL)
171*e7258c1aSMartin K. Petersen 		return false;
172*e7258c1aSMartin K. Petersen 
173*e7258c1aSMartin K. Petersen 	if (bio_data_dir(bio) == READ && bi->verify_fn != NULL &&
174*e7258c1aSMartin K. Petersen 	    (bi->flags & INTEGRITY_FLAG_READ))
175*e7258c1aSMartin K. Petersen 		return true;
176*e7258c1aSMartin K. Petersen 
177*e7258c1aSMartin K. Petersen 	if (bio_data_dir(bio) == WRITE && bi->generate_fn != NULL &&
178*e7258c1aSMartin K. Petersen 	    (bi->flags & INTEGRITY_FLAG_WRITE))
179*e7258c1aSMartin K. Petersen 		return true;
180*e7258c1aSMartin K. Petersen 
181*e7258c1aSMartin K. Petersen 	return false;
1827ba1ba12SMartin K. Petersen }
1837ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_enabled);
1847ba1ba12SMartin K. Petersen 
1857ba1ba12SMartin K. Petersen /**
1867ba1ba12SMartin K. Petersen  * bio_integrity_hw_sectors - Convert 512b sectors to hardware ditto
1877ba1ba12SMartin K. Petersen  * @bi:		blk_integrity profile for device
1887ba1ba12SMartin K. Petersen  * @sectors:	Number of 512 sectors to convert
1897ba1ba12SMartin K. Petersen  *
1907ba1ba12SMartin K. Petersen  * Description: The block layer calculates everything in 512 byte
1917ba1ba12SMartin K. Petersen  * sectors but integrity metadata is done in terms of the hardware
1927ba1ba12SMartin K. Petersen  * sector size of the storage device.  Convert the block layer sectors
1937ba1ba12SMartin K. Petersen  * to physical sectors.
1947ba1ba12SMartin K. Petersen  */
195b984679eSJens Axboe static inline unsigned int bio_integrity_hw_sectors(struct blk_integrity *bi,
196b984679eSJens Axboe 						    unsigned int sectors)
1977ba1ba12SMartin K. Petersen {
1987ba1ba12SMartin K. Petersen 	/* At this point there are only 512b or 4096b DIF/EPP devices */
1997ba1ba12SMartin K. Petersen 	if (bi->sector_size == 4096)
2007ba1ba12SMartin K. Petersen 		return sectors >>= 3;
2017ba1ba12SMartin K. Petersen 
2027ba1ba12SMartin K. Petersen 	return sectors;
2037ba1ba12SMartin K. Petersen }
2047ba1ba12SMartin K. Petersen 
205d57a5f7cSKent Overstreet static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
206d57a5f7cSKent Overstreet 					       unsigned int sectors)
207d57a5f7cSKent Overstreet {
208d57a5f7cSKent Overstreet 	return bio_integrity_hw_sectors(bi, sectors) * bi->tuple_size;
209d57a5f7cSKent Overstreet }
210d57a5f7cSKent Overstreet 
2117ba1ba12SMartin K. Petersen /**
2127ba1ba12SMartin K. Petersen  * bio_integrity_tag_size - Retrieve integrity tag space
2137ba1ba12SMartin K. Petersen  * @bio:	bio to inspect
2147ba1ba12SMartin K. Petersen  *
2157ba1ba12SMartin K. Petersen  * Description: Returns the maximum number of tag bytes that can be
2167ba1ba12SMartin K. Petersen  * attached to this bio. Filesystems can use this to determine how
2177ba1ba12SMartin K. Petersen  * much metadata to attach to an I/O.
2187ba1ba12SMartin K. Petersen  */
2197ba1ba12SMartin K. Petersen unsigned int bio_integrity_tag_size(struct bio *bio)
2207ba1ba12SMartin K. Petersen {
2217ba1ba12SMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
2227ba1ba12SMartin K. Petersen 
2234f024f37SKent Overstreet 	BUG_ON(bio->bi_iter.bi_size == 0);
2247ba1ba12SMartin K. Petersen 
2254f024f37SKent Overstreet 	return bi->tag_size * (bio->bi_iter.bi_size / bi->sector_size);
2267ba1ba12SMartin K. Petersen }
2277ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_tag_size);
2287ba1ba12SMartin K. Petersen 
2290b4ef8deSRashika Kheria static int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len,
2300b4ef8deSRashika Kheria 			     int set)
2317ba1ba12SMartin K. Petersen {
2327ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
2337ba1ba12SMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
2347ba1ba12SMartin K. Petersen 	unsigned int nr_sectors;
2357ba1ba12SMartin K. Petersen 
2367ba1ba12SMartin K. Petersen 	BUG_ON(bip->bip_buf == NULL);
2377ba1ba12SMartin K. Petersen 
2387ba1ba12SMartin K. Petersen 	if (bi->tag_size == 0)
2397ba1ba12SMartin K. Petersen 		return -1;
2407ba1ba12SMartin K. Petersen 
241b984679eSJens Axboe 	nr_sectors = bio_integrity_hw_sectors(bi,
242b984679eSJens Axboe 					DIV_ROUND_UP(len, bi->tag_size));
2437ba1ba12SMartin K. Petersen 
244d57a5f7cSKent Overstreet 	if (nr_sectors * bi->tuple_size > bip->bip_iter.bi_size) {
245d57a5f7cSKent Overstreet 		printk(KERN_ERR "%s: tag too big for bio: %u > %u\n", __func__,
246d57a5f7cSKent Overstreet 		       nr_sectors * bi->tuple_size, bip->bip_iter.bi_size);
2477ba1ba12SMartin K. Petersen 		return -1;
2487ba1ba12SMartin K. Petersen 	}
2497ba1ba12SMartin K. Petersen 
2507ba1ba12SMartin K. Petersen 	if (set)
2517ba1ba12SMartin K. Petersen 		bi->set_tag_fn(bip->bip_buf, tag_buf, nr_sectors);
2527ba1ba12SMartin K. Petersen 	else
2537ba1ba12SMartin K. Petersen 		bi->get_tag_fn(bip->bip_buf, tag_buf, nr_sectors);
2547ba1ba12SMartin K. Petersen 
2557ba1ba12SMartin K. Petersen 	return 0;
2567ba1ba12SMartin K. Petersen }
2577ba1ba12SMartin K. Petersen 
2587ba1ba12SMartin K. Petersen /**
2597ba1ba12SMartin K. Petersen  * bio_integrity_set_tag - Attach a tag buffer to a bio
2607ba1ba12SMartin K. Petersen  * @bio:	bio to attach buffer to
2617ba1ba12SMartin K. Petersen  * @tag_buf:	Pointer to a buffer containing tag data
2627ba1ba12SMartin K. Petersen  * @len:	Length of the included buffer
2637ba1ba12SMartin K. Petersen  *
2647ba1ba12SMartin K. Petersen  * Description: Use this function to tag a bio by leveraging the extra
2657ba1ba12SMartin K. Petersen  * space provided by devices formatted with integrity protection.  The
2667ba1ba12SMartin K. Petersen  * size of the integrity buffer must be <= to the size reported by
2677ba1ba12SMartin K. Petersen  * bio_integrity_tag_size().
2687ba1ba12SMartin K. Petersen  */
2697ba1ba12SMartin K. Petersen int bio_integrity_set_tag(struct bio *bio, void *tag_buf, unsigned int len)
2707ba1ba12SMartin K. Petersen {
2717ba1ba12SMartin K. Petersen 	BUG_ON(bio_data_dir(bio) != WRITE);
2727ba1ba12SMartin K. Petersen 
2737ba1ba12SMartin K. Petersen 	return bio_integrity_tag(bio, tag_buf, len, 1);
2747ba1ba12SMartin K. Petersen }
2757ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_set_tag);
2767ba1ba12SMartin K. Petersen 
2777ba1ba12SMartin K. Petersen /**
2787ba1ba12SMartin K. Petersen  * bio_integrity_get_tag - Retrieve a tag buffer from a bio
2797ba1ba12SMartin K. Petersen  * @bio:	bio to retrieve buffer from
2807ba1ba12SMartin K. Petersen  * @tag_buf:	Pointer to a buffer for the tag data
2817ba1ba12SMartin K. Petersen  * @len:	Length of the target buffer
2827ba1ba12SMartin K. Petersen  *
2837ba1ba12SMartin K. Petersen  * Description: Use this function to retrieve the tag buffer from a
2847ba1ba12SMartin K. Petersen  * completed I/O. The size of the integrity buffer must be <= to the
2857ba1ba12SMartin K. Petersen  * size reported by bio_integrity_tag_size().
2867ba1ba12SMartin K. Petersen  */
2877ba1ba12SMartin K. Petersen int bio_integrity_get_tag(struct bio *bio, void *tag_buf, unsigned int len)
2887ba1ba12SMartin K. Petersen {
2897ba1ba12SMartin K. Petersen 	BUG_ON(bio_data_dir(bio) != READ);
2907ba1ba12SMartin K. Petersen 
2917ba1ba12SMartin K. Petersen 	return bio_integrity_tag(bio, tag_buf, len, 0);
2927ba1ba12SMartin K. Petersen }
2937ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_get_tag);
2947ba1ba12SMartin K. Petersen 
2957ba1ba12SMartin K. Petersen /**
296bf36f9cfSGu Zheng  * bio_integrity_generate_verify - Generate/verify integrity metadata for a bio
297bf36f9cfSGu Zheng  * @bio:	bio to generate/verify integrity metadata for
298bf36f9cfSGu Zheng  * @operate:	operate number, 1 for generate, 0 for verify
2997ba1ba12SMartin K. Petersen  */
300bf36f9cfSGu Zheng static int bio_integrity_generate_verify(struct bio *bio, int operate)
3017ba1ba12SMartin K. Petersen {
3027ba1ba12SMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
3037ba1ba12SMartin K. Petersen 	struct blk_integrity_exchg bix;
3040bc69973SMartin K. Petersen 	struct bio_vec *bv;
305bf36f9cfSGu Zheng 	sector_t sector;
3060bc69973SMartin K. Petersen 	unsigned int sectors, ret = 0, i;
3077ba1ba12SMartin K. Petersen 	void *prot_buf = bio->bi_integrity->bip_buf;
3087ba1ba12SMartin K. Petersen 
309bf36f9cfSGu Zheng 	if (operate)
310bf36f9cfSGu Zheng 		sector = bio->bi_iter.bi_sector;
311bf36f9cfSGu Zheng 	else
312bf36f9cfSGu Zheng 		sector = bio->bi_integrity->bip_iter.bi_sector;
313bf36f9cfSGu Zheng 
3147ba1ba12SMartin K. Petersen 	bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
3157ba1ba12SMartin K. Petersen 	bix.sector_size = bi->sector_size;
3167ba1ba12SMartin K. Petersen 
3170bc69973SMartin K. Petersen 	bio_for_each_segment_all(bv, bio, i) {
3180bc69973SMartin K. Petersen 		void *kaddr = kmap_atomic(bv->bv_page);
3190bc69973SMartin K. Petersen 		bix.data_buf = kaddr + bv->bv_offset;
3200bc69973SMartin K. Petersen 		bix.data_size = bv->bv_len;
3217ba1ba12SMartin K. Petersen 		bix.prot_buf = prot_buf;
3227ba1ba12SMartin K. Petersen 		bix.sector = sector;
3237ba1ba12SMartin K. Petersen 
3240bc69973SMartin K. Petersen 		if (operate)
3257ba1ba12SMartin K. Petersen 			bi->generate_fn(&bix);
3260bc69973SMartin K. Petersen 		else {
327bf36f9cfSGu Zheng 			ret = bi->verify_fn(&bix);
328bf36f9cfSGu Zheng 			if (ret) {
329bf36f9cfSGu Zheng 				kunmap_atomic(kaddr);
330bf36f9cfSGu Zheng 				return ret;
331bf36f9cfSGu Zheng 			}
332bf36f9cfSGu Zheng 		}
3337ba1ba12SMartin K. Petersen 
3340bc69973SMartin K. Petersen 		sectors = bv->bv_len / bi->sector_size;
3357ba1ba12SMartin K. Petersen 		sector += sectors;
3367ba1ba12SMartin K. Petersen 		prot_buf += sectors * bi->tuple_size;
3377ba1ba12SMartin K. Petersen 
338e8e3c3d6SCong Wang 		kunmap_atomic(kaddr);
3397ba1ba12SMartin K. Petersen 	}
340bf36f9cfSGu Zheng 	return ret;
341bf36f9cfSGu Zheng }
342bf36f9cfSGu Zheng 
343bf36f9cfSGu Zheng /**
344bf36f9cfSGu Zheng  * bio_integrity_generate - Generate integrity metadata for a bio
345bf36f9cfSGu Zheng  * @bio:	bio to generate integrity metadata for
346bf36f9cfSGu Zheng  *
347bf36f9cfSGu Zheng  * Description: Generates integrity metadata for a bio by calling the
348bf36f9cfSGu Zheng  * block device's generation callback function.  The bio must have a
349bf36f9cfSGu Zheng  * bip attached with enough room to accommodate the generated
350bf36f9cfSGu Zheng  * integrity metadata.
351bf36f9cfSGu Zheng  */
352bf36f9cfSGu Zheng static void bio_integrity_generate(struct bio *bio)
353bf36f9cfSGu Zheng {
354bf36f9cfSGu Zheng 	bio_integrity_generate_verify(bio, 1);
3557ba1ba12SMartin K. Petersen }
3567ba1ba12SMartin K. Petersen 
3579c02f2b0SJens Axboe static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi)
3589c02f2b0SJens Axboe {
3599c02f2b0SJens Axboe 	if (bi)
3609c02f2b0SJens Axboe 		return bi->tuple_size;
3619c02f2b0SJens Axboe 
3629c02f2b0SJens Axboe 	return 0;
3639c02f2b0SJens Axboe }
3649c02f2b0SJens Axboe 
3657ba1ba12SMartin K. Petersen /**
3667ba1ba12SMartin K. Petersen  * bio_integrity_prep - Prepare bio for integrity I/O
3677ba1ba12SMartin K. Petersen  * @bio:	bio to prepare
3687ba1ba12SMartin K. Petersen  *
3697ba1ba12SMartin K. Petersen  * Description: Allocates a buffer for integrity metadata, maps the
3707ba1ba12SMartin K. Petersen  * pages and attaches them to a bio.  The bio must have data
3717ba1ba12SMartin K. Petersen  * direction, target device and start sector set priot to calling.  In
3727ba1ba12SMartin K. Petersen  * the WRITE case, integrity metadata will be generated using the
3737ba1ba12SMartin K. Petersen  * block device's integrity function.  In the READ case, the buffer
3747ba1ba12SMartin K. Petersen  * will be prepared for DMA and a suitable end_io handler set up.
3757ba1ba12SMartin K. Petersen  */
3767ba1ba12SMartin K. Petersen int bio_integrity_prep(struct bio *bio)
3777ba1ba12SMartin K. Petersen {
3787ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip;
3797ba1ba12SMartin K. Petersen 	struct blk_integrity *bi;
3807ba1ba12SMartin K. Petersen 	struct request_queue *q;
3817ba1ba12SMartin K. Petersen 	void *buf;
3827ba1ba12SMartin K. Petersen 	unsigned long start, end;
3837ba1ba12SMartin K. Petersen 	unsigned int len, nr_pages;
3847ba1ba12SMartin K. Petersen 	unsigned int bytes, offset, i;
3857ba1ba12SMartin K. Petersen 	unsigned int sectors;
3867ba1ba12SMartin K. Petersen 
3877ba1ba12SMartin K. Petersen 	bi = bdev_get_integrity(bio->bi_bdev);
3887ba1ba12SMartin K. Petersen 	q = bdev_get_queue(bio->bi_bdev);
3897ba1ba12SMartin K. Petersen 	BUG_ON(bi == NULL);
3907ba1ba12SMartin K. Petersen 	BUG_ON(bio_integrity(bio));
3917ba1ba12SMartin K. Petersen 
3927ba1ba12SMartin K. Petersen 	sectors = bio_integrity_hw_sectors(bi, bio_sectors(bio));
3937ba1ba12SMartin K. Petersen 
3947ba1ba12SMartin K. Petersen 	/* Allocate kernel buffer for protection data */
3957ba1ba12SMartin K. Petersen 	len = sectors * blk_integrity_tuple_size(bi);
39672f46503SDavid Rientjes 	buf = kmalloc(len, GFP_NOIO | q->bounce_gfp);
3977ba1ba12SMartin K. Petersen 	if (unlikely(buf == NULL)) {
3987ba1ba12SMartin K. Petersen 		printk(KERN_ERR "could not allocate integrity buffer\n");
399220eb7fdSAndrew Morton 		return -ENOMEM;
4007ba1ba12SMartin K. Petersen 	}
4017ba1ba12SMartin K. Petersen 
4027ba1ba12SMartin K. Petersen 	end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
4037ba1ba12SMartin K. Petersen 	start = ((unsigned long) buf) >> PAGE_SHIFT;
4047ba1ba12SMartin K. Petersen 	nr_pages = end - start;
4057ba1ba12SMartin K. Petersen 
4067ba1ba12SMartin K. Petersen 	/* Allocate bio integrity payload and integrity vectors */
4077ba1ba12SMartin K. Petersen 	bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
4087ba1ba12SMartin K. Petersen 	if (unlikely(bip == NULL)) {
4097ba1ba12SMartin K. Petersen 		printk(KERN_ERR "could not allocate data integrity bioset\n");
4107ba1ba12SMartin K. Petersen 		kfree(buf);
4117ba1ba12SMartin K. Petersen 		return -EIO;
4127ba1ba12SMartin K. Petersen 	}
4137ba1ba12SMartin K. Petersen 
41429ed7813SKent Overstreet 	bip->bip_owns_buf = 1;
4157ba1ba12SMartin K. Petersen 	bip->bip_buf = buf;
416d57a5f7cSKent Overstreet 	bip->bip_iter.bi_size = len;
417d57a5f7cSKent Overstreet 	bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
4187ba1ba12SMartin K. Petersen 
4197ba1ba12SMartin K. Petersen 	/* Map it */
4207ba1ba12SMartin K. Petersen 	offset = offset_in_page(buf);
4217ba1ba12SMartin K. Petersen 	for (i = 0 ; i < nr_pages ; i++) {
4227ba1ba12SMartin K. Petersen 		int ret;
4237ba1ba12SMartin K. Petersen 		bytes = PAGE_SIZE - offset;
4247ba1ba12SMartin K. Petersen 
4257ba1ba12SMartin K. Petersen 		if (len <= 0)
4267ba1ba12SMartin K. Petersen 			break;
4277ba1ba12SMartin K. Petersen 
4287ba1ba12SMartin K. Petersen 		if (bytes > len)
4297ba1ba12SMartin K. Petersen 			bytes = len;
4307ba1ba12SMartin K. Petersen 
4317ba1ba12SMartin K. Petersen 		ret = bio_integrity_add_page(bio, virt_to_page(buf),
4327ba1ba12SMartin K. Petersen 					     bytes, offset);
4337ba1ba12SMartin K. Petersen 
4347ba1ba12SMartin K. Petersen 		if (ret == 0)
4357ba1ba12SMartin K. Petersen 			return 0;
4367ba1ba12SMartin K. Petersen 
4377ba1ba12SMartin K. Petersen 		if (ret < bytes)
4387ba1ba12SMartin K. Petersen 			break;
4397ba1ba12SMartin K. Petersen 
4407ba1ba12SMartin K. Petersen 		buf += bytes;
4417ba1ba12SMartin K. Petersen 		len -= bytes;
4427ba1ba12SMartin K. Petersen 		offset = 0;
4437ba1ba12SMartin K. Petersen 	}
4447ba1ba12SMartin K. Petersen 
4457ba1ba12SMartin K. Petersen 	/* Install custom I/O completion handler if read verify is enabled */
4467ba1ba12SMartin K. Petersen 	if (bio_data_dir(bio) == READ) {
4477ba1ba12SMartin K. Petersen 		bip->bip_end_io = bio->bi_end_io;
4487ba1ba12SMartin K. Petersen 		bio->bi_end_io = bio_integrity_endio;
4497ba1ba12SMartin K. Petersen 	}
4507ba1ba12SMartin K. Petersen 
4517ba1ba12SMartin K. Petersen 	/* Auto-generate integrity metadata if this is a write */
4527ba1ba12SMartin K. Petersen 	if (bio_data_dir(bio) == WRITE)
4537ba1ba12SMartin K. Petersen 		bio_integrity_generate(bio);
4547ba1ba12SMartin K. Petersen 
4557ba1ba12SMartin K. Petersen 	return 0;
4567ba1ba12SMartin K. Petersen }
4577ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_prep);
4587ba1ba12SMartin K. Petersen 
4597ba1ba12SMartin K. Petersen /**
4607ba1ba12SMartin K. Petersen  * bio_integrity_verify - Verify integrity metadata for a bio
4617ba1ba12SMartin K. Petersen  * @bio:	bio to verify
4627ba1ba12SMartin K. Petersen  *
4637ba1ba12SMartin K. Petersen  * Description: This function is called to verify the integrity of a
4647ba1ba12SMartin K. Petersen  * bio.	 The data in the bio io_vec is compared to the integrity
4657ba1ba12SMartin K. Petersen  * metadata returned by the HBA.
4667ba1ba12SMartin K. Petersen  */
4677ba1ba12SMartin K. Petersen static int bio_integrity_verify(struct bio *bio)
4687ba1ba12SMartin K. Petersen {
469bf36f9cfSGu Zheng 	return bio_integrity_generate_verify(bio, 0);
4707ba1ba12SMartin K. Petersen }
4717ba1ba12SMartin K. Petersen 
4727ba1ba12SMartin K. Petersen /**
4737ba1ba12SMartin K. Petersen  * bio_integrity_verify_fn - Integrity I/O completion worker
4747ba1ba12SMartin K. Petersen  * @work:	Work struct stored in bio to be verified
4757ba1ba12SMartin K. Petersen  *
4767ba1ba12SMartin K. Petersen  * Description: This workqueue function is called to complete a READ
4777ba1ba12SMartin K. Petersen  * request.  The function verifies the transferred integrity metadata
4787ba1ba12SMartin K. Petersen  * and then calls the original bio end_io function.
4797ba1ba12SMartin K. Petersen  */
4807ba1ba12SMartin K. Petersen static void bio_integrity_verify_fn(struct work_struct *work)
4817ba1ba12SMartin K. Petersen {
4827ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip =
4837ba1ba12SMartin K. Petersen 		container_of(work, struct bio_integrity_payload, bip_work);
4847ba1ba12SMartin K. Petersen 	struct bio *bio = bip->bip_bio;
4857b24fc4dSMartin K. Petersen 	int error;
4867ba1ba12SMartin K. Petersen 
4877b24fc4dSMartin K. Petersen 	error = bio_integrity_verify(bio);
4887ba1ba12SMartin K. Petersen 
4897ba1ba12SMartin K. Petersen 	/* Restore original bio completion handler */
4907ba1ba12SMartin K. Petersen 	bio->bi_end_io = bip->bip_end_io;
491196d38bcSKent Overstreet 	bio_endio_nodec(bio, error);
4927ba1ba12SMartin K. Petersen }
4937ba1ba12SMartin K. Petersen 
4947ba1ba12SMartin K. Petersen /**
4957ba1ba12SMartin K. Petersen  * bio_integrity_endio - Integrity I/O completion function
4967ba1ba12SMartin K. Petersen  * @bio:	Protected bio
4977ba1ba12SMartin K. Petersen  * @error:	Pointer to errno
4987ba1ba12SMartin K. Petersen  *
4997ba1ba12SMartin K. Petersen  * Description: Completion for integrity I/O
5007ba1ba12SMartin K. Petersen  *
5017ba1ba12SMartin K. Petersen  * Normally I/O completion is done in interrupt context.  However,
5027ba1ba12SMartin K. Petersen  * verifying I/O integrity is a time-consuming task which must be run
5037ba1ba12SMartin K. Petersen  * in process context.	This function postpones completion
5047ba1ba12SMartin K. Petersen  * accordingly.
5057ba1ba12SMartin K. Petersen  */
5067ba1ba12SMartin K. Petersen void bio_integrity_endio(struct bio *bio, int error)
5077ba1ba12SMartin K. Petersen {
5087ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
5097ba1ba12SMartin K. Petersen 
5107ba1ba12SMartin K. Petersen 	BUG_ON(bip->bip_bio != bio);
5117ba1ba12SMartin K. Petersen 
5127b24fc4dSMartin K. Petersen 	/* In case of an I/O error there is no point in verifying the
5137b24fc4dSMartin K. Petersen 	 * integrity metadata.  Restore original bio end_io handler
5147b24fc4dSMartin K. Petersen 	 * and run it.
5157b24fc4dSMartin K. Petersen 	 */
5167b24fc4dSMartin K. Petersen 	if (error) {
5177b24fc4dSMartin K. Petersen 		bio->bi_end_io = bip->bip_end_io;
51816f408dcSSagi Grimberg 		bio_endio_nodec(bio, error);
5197b24fc4dSMartin K. Petersen 
5207b24fc4dSMartin K. Petersen 		return;
5217b24fc4dSMartin K. Petersen 	}
5227b24fc4dSMartin K. Petersen 
5237ba1ba12SMartin K. Petersen 	INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
5247ba1ba12SMartin K. Petersen 	queue_work(kintegrityd_wq, &bip->bip_work);
5257ba1ba12SMartin K. Petersen }
5267ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_endio);
5277ba1ba12SMartin K. Petersen 
5287ba1ba12SMartin K. Petersen /**
5297ba1ba12SMartin K. Petersen  * bio_integrity_advance - Advance integrity vector
5307ba1ba12SMartin K. Petersen  * @bio:	bio whose integrity vector to update
5317ba1ba12SMartin K. Petersen  * @bytes_done:	number of data bytes that have been completed
5327ba1ba12SMartin K. Petersen  *
5337ba1ba12SMartin K. Petersen  * Description: This function calculates how many integrity bytes the
5347ba1ba12SMartin K. Petersen  * number of completed data bytes correspond to and advances the
5357ba1ba12SMartin K. Petersen  * integrity vector accordingly.
5367ba1ba12SMartin K. Petersen  */
5377ba1ba12SMartin K. Petersen void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
5387ba1ba12SMartin K. Petersen {
5397ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
5407ba1ba12SMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
541d57a5f7cSKent Overstreet 	unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
5427ba1ba12SMartin K. Petersen 
543d57a5f7cSKent Overstreet 	bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
5447ba1ba12SMartin K. Petersen }
5457ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_advance);
5467ba1ba12SMartin K. Petersen 
5477ba1ba12SMartin K. Petersen /**
5487ba1ba12SMartin K. Petersen  * bio_integrity_trim - Trim integrity vector
5497ba1ba12SMartin K. Petersen  * @bio:	bio whose integrity vector to update
5507ba1ba12SMartin K. Petersen  * @offset:	offset to first data sector
5517ba1ba12SMartin K. Petersen  * @sectors:	number of data sectors
5527ba1ba12SMartin K. Petersen  *
5537ba1ba12SMartin K. Petersen  * Description: Used to trim the integrity vector in a cloned bio.
5547ba1ba12SMartin K. Petersen  * The ivec will be advanced corresponding to 'offset' data sectors
5557ba1ba12SMartin K. Petersen  * and the length will be truncated corresponding to 'len' data
5567ba1ba12SMartin K. Petersen  * sectors.
5577ba1ba12SMartin K. Petersen  */
558b984679eSJens Axboe void bio_integrity_trim(struct bio *bio, unsigned int offset,
559b984679eSJens Axboe 			unsigned int sectors)
5607ba1ba12SMartin K. Petersen {
5617ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip = bio->bi_integrity;
5627ba1ba12SMartin K. Petersen 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
5637ba1ba12SMartin K. Petersen 
564d57a5f7cSKent Overstreet 	bio_integrity_advance(bio, offset << 9);
565d57a5f7cSKent Overstreet 	bip->bip_iter.bi_size = bio_integrity_bytes(bi, sectors);
5667ba1ba12SMartin K. Petersen }
5677ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_trim);
5687ba1ba12SMartin K. Petersen 
5697ba1ba12SMartin K. Petersen /**
5707ba1ba12SMartin K. Petersen  * bio_integrity_clone - Callback for cloning bios with integrity metadata
5717ba1ba12SMartin K. Petersen  * @bio:	New bio
5727ba1ba12SMartin K. Petersen  * @bio_src:	Original bio
57387092698Sun'ichi Nomura  * @gfp_mask:	Memory allocation mask
5747ba1ba12SMartin K. Petersen  *
5757ba1ba12SMartin K. Petersen  * Description:	Called to allocate a bip when cloning a bio
5767ba1ba12SMartin K. Petersen  */
5777878cba9SMartin K. Petersen int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
5781e2a410fSKent Overstreet 			gfp_t gfp_mask)
5797ba1ba12SMartin K. Petersen {
5807ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip_src = bio_src->bi_integrity;
5817ba1ba12SMartin K. Petersen 	struct bio_integrity_payload *bip;
5827ba1ba12SMartin K. Petersen 
5837ba1ba12SMartin K. Petersen 	BUG_ON(bip_src == NULL);
5847ba1ba12SMartin K. Petersen 
5851e2a410fSKent Overstreet 	bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
5867ba1ba12SMartin K. Petersen 
5877ba1ba12SMartin K. Petersen 	if (bip == NULL)
5887ba1ba12SMartin K. Petersen 		return -EIO;
5897ba1ba12SMartin K. Petersen 
5907ba1ba12SMartin K. Petersen 	memcpy(bip->bip_vec, bip_src->bip_vec,
5917ba1ba12SMartin K. Petersen 	       bip_src->bip_vcnt * sizeof(struct bio_vec));
5927ba1ba12SMartin K. Petersen 
5937ba1ba12SMartin K. Petersen 	bip->bip_vcnt = bip_src->bip_vcnt;
594d57a5f7cSKent Overstreet 	bip->bip_iter = bip_src->bip_iter;
5957ba1ba12SMartin K. Petersen 
5967ba1ba12SMartin K. Petersen 	return 0;
5977ba1ba12SMartin K. Petersen }
5987ba1ba12SMartin K. Petersen EXPORT_SYMBOL(bio_integrity_clone);
5997ba1ba12SMartin K. Petersen 
6007878cba9SMartin K. Petersen int bioset_integrity_create(struct bio_set *bs, int pool_size)
6017ba1ba12SMartin K. Petersen {
602a91a2785SMartin K. Petersen 	if (bs->bio_integrity_pool)
603a91a2785SMartin K. Petersen 		return 0;
604a91a2785SMartin K. Petersen 
6059f060e22SKent Overstreet 	bs->bio_integrity_pool = mempool_create_slab_pool(pool_size, bip_slab);
6067878cba9SMartin K. Petersen 	if (!bs->bio_integrity_pool)
6077878cba9SMartin K. Petersen 		return -1;
6086d2a78e7SMartin K. Petersen 
609a6c39cb4SFabian Frederick 	bs->bvec_integrity_pool = biovec_create_pool(pool_size);
610bc5c8f07SGu Zheng 	if (!bs->bvec_integrity_pool) {
611bc5c8f07SGu Zheng 		mempool_destroy(bs->bio_integrity_pool);
612bc5c8f07SGu Zheng 		return -1;
613bc5c8f07SGu Zheng 	}
614bc5c8f07SGu Zheng 
6157ba1ba12SMartin K. Petersen 	return 0;
6167ba1ba12SMartin K. Petersen }
6177878cba9SMartin K. Petersen EXPORT_SYMBOL(bioset_integrity_create);
6187878cba9SMartin K. Petersen 
6197878cba9SMartin K. Petersen void bioset_integrity_free(struct bio_set *bs)
6207878cba9SMartin K. Petersen {
6217878cba9SMartin K. Petersen 	if (bs->bio_integrity_pool)
6227878cba9SMartin K. Petersen 		mempool_destroy(bs->bio_integrity_pool);
6239f060e22SKent Overstreet 
6249f060e22SKent Overstreet 	if (bs->bvec_integrity_pool)
625adbe6991SBjorn Helgaas 		mempool_destroy(bs->bvec_integrity_pool);
6267878cba9SMartin K. Petersen }
6277878cba9SMartin K. Petersen EXPORT_SYMBOL(bioset_integrity_free);
6287878cba9SMartin K. Petersen 
6297878cba9SMartin K. Petersen void __init bio_integrity_init(void)
6307878cba9SMartin K. Petersen {
631a6e8dc46STejun Heo 	/*
632a6e8dc46STejun Heo 	 * kintegrityd won't block much but may burn a lot of CPU cycles.
633a6e8dc46STejun Heo 	 * Make it highpri CPU intensive wq with max concurrency of 1.
634a6e8dc46STejun Heo 	 */
635a6e8dc46STejun Heo 	kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
636a6e8dc46STejun Heo 					 WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
6377878cba9SMartin K. Petersen 	if (!kintegrityd_wq)
6387878cba9SMartin K. Petersen 		panic("Failed to create kintegrityd\n");
6397878cba9SMartin K. Petersen 
6409f060e22SKent Overstreet 	bip_slab = kmem_cache_create("bio_integrity_payload",
6419f060e22SKent Overstreet 				     sizeof(struct bio_integrity_payload) +
6429f060e22SKent Overstreet 				     sizeof(struct bio_vec) * BIP_INLINE_VECS,
6439f060e22SKent Overstreet 				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
6449f060e22SKent Overstreet 	if (!bip_slab)
6459f060e22SKent Overstreet 		panic("Failed to create slab\n");
6467878cba9SMartin K. Petersen }
647