Blame view

block/bio-integrity.c 14 KB
7ba1ba12e   Martin K. Petersen   block: Block laye...
1
2
3
  /*
   * bio-integrity.c - bio data integrity extensions
   *
7878cba9f   Martin K. Petersen   block: Create bip...
4
   * Copyright (C) 2007, 2008, 2009 Oracle Corporation
7ba1ba12e   Martin K. Petersen   block: Block laye...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   * Written by: Martin K. Petersen <martin.petersen@oracle.com>
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License version
   * 2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; see the file COPYING.  If not, write to
   * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
   * USA.
   *
   */
  
  #include <linux/blkdev.h>
  #include <linux/mempool.h>
afeacc8c1   Paul Gortmaker   fs: add export.h ...
25
  #include <linux/export.h>
7ba1ba12e   Martin K. Petersen   block: Block laye...
26
27
  #include <linux/bio.h>
  #include <linux/workqueue.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
28
  #include <linux/slab.h>
7ba1ba12e   Martin K. Petersen   block: Block laye...
29

9f060e223   Kent Overstreet   block: Convert in...
30
  #define BIP_INLINE_VECS	4
7878cba9f   Martin K. Petersen   block: Create bip...
31

9f060e223   Kent Overstreet   block: Convert in...
32
  static struct kmem_cache *bip_slab;
7ba1ba12e   Martin K. Petersen   block: Block laye...
33
34
35
  static struct workqueue_struct *kintegrityd_wq;
  
  /**
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
36
   * bio_integrity_alloc - Allocate integrity payload and attach it to bio
7ba1ba12e   Martin K. Petersen   block: Block laye...
37
38
39
   * @bio:	bio to attach integrity metadata to
   * @gfp_mask:	Memory allocation mask
   * @nr_vecs:	Number of integrity metadata scatter-gather elements
7ba1ba12e   Martin K. Petersen   block: Block laye...
40
41
42
43
44
   *
   * Description: This function prepares a bio for attaching integrity
   * metadata.  nr_vecs specifies the maximum number of pages containing
   * integrity metadata that can be attached.
   */
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
45
46
47
  struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
  						  gfp_t gfp_mask,
  						  unsigned int nr_vecs)
7ba1ba12e   Martin K. Petersen   block: Block laye...
48
49
  {
  	struct bio_integrity_payload *bip;
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
50
  	struct bio_set *bs = bio->bi_pool;
9f060e223   Kent Overstreet   block: Convert in...
51
52
53
54
55
56
57
58
  	unsigned long idx = BIO_POOL_NONE;
  	unsigned inline_vecs;
  
  	if (!bs) {
  		bip = kmalloc(sizeof(struct bio_integrity_payload) +
  			      sizeof(struct bio_vec) * nr_vecs, gfp_mask);
  		inline_vecs = nr_vecs;
  	} else {
7878cba9f   Martin K. Petersen   block: Create bip...
59
  		bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
9f060e223   Kent Overstreet   block: Convert in...
60
  		inline_vecs = BIP_INLINE_VECS;
7ba1ba12e   Martin K. Petersen   block: Block laye...
61
  	}
9f060e223   Kent Overstreet   block: Convert in...
62
63
  	if (unlikely(!bip))
  		return NULL;
7878cba9f   Martin K. Petersen   block: Create bip...
64
  	memset(bip, 0, sizeof(*bip));
9f060e223   Kent Overstreet   block: Convert in...
65
66
67
68
69
  	if (nr_vecs > inline_vecs) {
  		bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx,
  					  bs->bvec_integrity_pool);
  		if (!bip->bip_vec)
  			goto err;
cbcd1054a   Gu Zheng   bio-integrity: ad...
70
  		bip->bip_max_vcnt = bvec_nr_vecs(idx);
9f060e223   Kent Overstreet   block: Convert in...
71
72
  	} else {
  		bip->bip_vec = bip->bip_inline_vecs;
cbcd1054a   Gu Zheng   bio-integrity: ad...
73
  		bip->bip_max_vcnt = inline_vecs;
9f060e223   Kent Overstreet   block: Convert in...
74
  	}
7878cba9f   Martin K. Petersen   block: Create bip...
75
  	bip->bip_slab = idx;
7ba1ba12e   Martin K. Petersen   block: Block laye...
76
77
  	bip->bip_bio = bio;
  	bio->bi_integrity = bip;
180b2f95d   Martin K. Petersen   block: Replace bi...
78
  	bio->bi_rw |= REQ_INTEGRITY;
7ba1ba12e   Martin K. Petersen   block: Block laye...
79
80
  
  	return bip;
9f060e223   Kent Overstreet   block: Convert in...
81
82
83
  err:
  	mempool_free(bip, bs->bio_integrity_pool);
  	return NULL;
7ba1ba12e   Martin K. Petersen   block: Block laye...
84
  }
7ba1ba12e   Martin K. Petersen   block: Block laye...
85
86
87
88
89
  EXPORT_SYMBOL(bio_integrity_alloc);
  
  /**
   * bio_integrity_free - Free bio integrity payload
   * @bio:	bio containing bip to be freed
7ba1ba12e   Martin K. Petersen   block: Block laye...
90
91
92
93
   *
   * Description: Used to free the integrity portion of a bio. Usually
   * called from bio_free().
   */
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
94
  void bio_integrity_free(struct bio *bio)
7ba1ba12e   Martin K. Petersen   block: Block laye...
95
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
96
  	struct bio_integrity_payload *bip = bio_integrity(bio);
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
97
  	struct bio_set *bs = bio->bi_pool;
b1f013885   Martin K. Petersen   block: Relocate b...
98
  	if (bip->bip_flags & BIP_BLOCK_INTEGRITY)
5f9378fa9   Martin K. Petersen   block: Remove bip...
99
100
  		kfree(page_address(bip->bip_vec->bv_page) +
  		      bip->bip_vec->bv_offset);
7ba1ba12e   Martin K. Petersen   block: Block laye...
101

9f060e223   Kent Overstreet   block: Convert in...
102
103
104
105
  	if (bs) {
  		if (bip->bip_slab != BIO_POOL_NONE)
  			bvec_free(bs->bvec_integrity_pool, bip->bip_vec,
  				  bip->bip_slab);
7878cba9f   Martin K. Petersen   block: Create bip...
106
  		mempool_free(bip, bs->bio_integrity_pool);
9f060e223   Kent Overstreet   block: Convert in...
107
108
109
  	} else {
  		kfree(bip);
  	}
7ba1ba12e   Martin K. Petersen   block: Block laye...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  
  	bio->bi_integrity = NULL;
  }
  EXPORT_SYMBOL(bio_integrity_free);
  
  /**
   * bio_integrity_add_page - Attach integrity metadata
   * @bio:	bio to update
   * @page:	page containing integrity metadata
   * @len:	number of bytes of integrity metadata in page
   * @offset:	start offset within page
   *
   * Description: Attach a page containing integrity metadata to bio.
   */
  int bio_integrity_add_page(struct bio *bio, struct page *page,
  			   unsigned int len, unsigned int offset)
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
127
  	struct bio_integrity_payload *bip = bio_integrity(bio);
7ba1ba12e   Martin K. Petersen   block: Block laye...
128
  	struct bio_vec *iv;
cbcd1054a   Gu Zheng   bio-integrity: ad...
129
  	if (bip->bip_vcnt >= bip->bip_max_vcnt) {
7ba1ba12e   Martin K. Petersen   block: Block laye...
130
131
132
133
  		printk(KERN_ERR "%s: bip_vec full
  ", __func__);
  		return 0;
  	}
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
134
  	iv = bip->bip_vec + bip->bip_vcnt;
7ba1ba12e   Martin K. Petersen   block: Block laye...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  
  	iv->bv_page = page;
  	iv->bv_len = len;
  	iv->bv_offset = offset;
  	bip->bip_vcnt++;
  
  	return len;
  }
  EXPORT_SYMBOL(bio_integrity_add_page);
  
  /**
   * bio_integrity_enabled - Check whether integrity can be passed
   * @bio:	bio to check
   *
   * Description: Determines whether bio_integrity_prep() can be called
   * on this bio or not.	bio data direction and target device must be
   * set prior to calling.  The functions honors the write_generate and
   * read_verify flags in sysfs.
   */
e7258c1a2   Martin K. Petersen   block: Get rid of...
154
  bool bio_integrity_enabled(struct bio *bio)
7ba1ba12e   Martin K. Petersen   block: Block laye...
155
  {
e7258c1a2   Martin K. Petersen   block: Get rid of...
156
  	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
e69f18f06   Martin K. Petersen   block: Ensure we ...
157
  	if (!bio_is_rw(bio))
e7258c1a2   Martin K. Petersen   block: Get rid of...
158
  		return false;
e69f18f06   Martin K. Petersen   block: Ensure we ...
159

7ba1ba12e   Martin K. Petersen   block: Block laye...
160
161
  	/* Already protected? */
  	if (bio_integrity(bio))
e7258c1a2   Martin K. Petersen   block: Get rid of...
162
163
164
165
166
167
  		return false;
  
  	if (bi == NULL)
  		return false;
  
  	if (bio_data_dir(bio) == READ && bi->verify_fn != NULL &&
8288f496e   Martin K. Petersen   block: Add prefix...
168
  	    (bi->flags & BLK_INTEGRITY_VERIFY))
e7258c1a2   Martin K. Petersen   block: Get rid of...
169
170
171
  		return true;
  
  	if (bio_data_dir(bio) == WRITE && bi->generate_fn != NULL &&
8288f496e   Martin K. Petersen   block: Add prefix...
172
  	    (bi->flags & BLK_INTEGRITY_GENERATE))
e7258c1a2   Martin K. Petersen   block: Get rid of...
173
  		return true;
7ba1ba12e   Martin K. Petersen   block: Block laye...
174

e7258c1a2   Martin K. Petersen   block: Get rid of...
175
  	return false;
7ba1ba12e   Martin K. Petersen   block: Block laye...
176
177
178
179
  }
  EXPORT_SYMBOL(bio_integrity_enabled);
  
  /**
3be91c4a3   Martin K. Petersen   block: Deprecate ...
180
   * bio_integrity_intervals - Return number of integrity intervals for a bio
7ba1ba12e   Martin K. Petersen   block: Block laye...
181
   * @bi:		blk_integrity profile for device
3be91c4a3   Martin K. Petersen   block: Deprecate ...
182
   * @sectors:	Size of the bio in 512-byte sectors
7ba1ba12e   Martin K. Petersen   block: Block laye...
183
184
   *
   * Description: The block layer calculates everything in 512 byte
3be91c4a3   Martin K. Petersen   block: Deprecate ...
185
186
187
   * sectors but integrity metadata is done in terms of the data integrity
   * interval size of the storage device.  Convert the block layer sectors
   * to the appropriate number of integrity intervals.
7ba1ba12e   Martin K. Petersen   block: Block laye...
188
   */
3be91c4a3   Martin K. Petersen   block: Deprecate ...
189
190
  static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi,
  						   unsigned int sectors)
7ba1ba12e   Martin K. Petersen   block: Block laye...
191
  {
5a2aa8730   Martin K. Petersen   block: Make prote...
192
  	return sectors >> (ilog2(bi->interval) - 9);
7ba1ba12e   Martin K. Petersen   block: Block laye...
193
  }
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
194
195
196
  static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi,
  					       unsigned int sectors)
  {
3be91c4a3   Martin K. Petersen   block: Deprecate ...
197
  	return bio_integrity_intervals(bi, sectors) * bi->tuple_size;
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
198
  }
7ba1ba12e   Martin K. Petersen   block: Block laye...
199
  /**
185930885   Martin K. Petersen   block: Clean up t...
200
   * bio_integrity_process - Process integrity metadata for a bio
bf36f9cfa   Gu Zheng   fs/bio-integrity:...
201
   * @bio:	bio to generate/verify integrity metadata for
185930885   Martin K. Petersen   block: Clean up t...
202
   * @proc_fn:	Pointer to the relevant processing function
7ba1ba12e   Martin K. Petersen   block: Block laye...
203
   */
185930885   Martin K. Petersen   block: Clean up t...
204
205
  static int bio_integrity_process(struct bio *bio,
  				 integrity_processing_fn *proc_fn)
7ba1ba12e   Martin K. Petersen   block: Block laye...
206
207
  {
  	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
185930885   Martin K. Petersen   block: Clean up t...
208
  	struct blk_integrity_iter iter;
594416a72   Darrick J. Wong   block: fix regres...
209
210
  	struct bvec_iter bviter;
  	struct bio_vec bv;
5f9378fa9   Martin K. Petersen   block: Remove bip...
211
  	struct bio_integrity_payload *bip = bio_integrity(bio);
594416a72   Darrick J. Wong   block: fix regres...
212
  	unsigned int ret = 0;
5f9378fa9   Martin K. Petersen   block: Remove bip...
213
214
  	void *prot_buf = page_address(bip->bip_vec->bv_page) +
  		bip->bip_vec->bv_offset;
7ba1ba12e   Martin K. Petersen   block: Block laye...
215

185930885   Martin K. Petersen   block: Clean up t...
216
217
218
219
  	iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
  	iter.interval = bi->interval;
  	iter.seed = bip_get_seed(bip);
  	iter.prot_buf = prot_buf;
7ba1ba12e   Martin K. Petersen   block: Block laye...
220

594416a72   Darrick J. Wong   block: fix regres...
221
222
  	bio_for_each_segment(bv, bio, bviter) {
  		void *kaddr = kmap_atomic(bv.bv_page);
7ba1ba12e   Martin K. Petersen   block: Block laye...
223

594416a72   Darrick J. Wong   block: fix regres...
224
225
  		iter.data_buf = kaddr + bv.bv_offset;
  		iter.data_size = bv.bv_len;
185930885   Martin K. Petersen   block: Clean up t...
226
227
228
229
230
231
  
  		ret = proc_fn(&iter);
  		if (ret) {
  			kunmap_atomic(kaddr);
  			return ret;
  		}
7ba1ba12e   Martin K. Petersen   block: Block laye...
232

e8e3c3d66   Cong Wang   fs: remove the se...
233
  		kunmap_atomic(kaddr);
7ba1ba12e   Martin K. Petersen   block: Block laye...
234
  	}
bf36f9cfa   Gu Zheng   fs/bio-integrity:...
235
236
237
238
  	return ret;
  }
  
  /**
7ba1ba12e   Martin K. Petersen   block: Block laye...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
   * bio_integrity_prep - Prepare bio for integrity I/O
   * @bio:	bio to prepare
   *
   * Description: Allocates a buffer for integrity metadata, maps the
   * pages and attaches them to a bio.  The bio must have data
   * direction, target device and start sector set priot to calling.  In
   * the WRITE case, integrity metadata will be generated using the
   * block device's integrity function.  In the READ case, the buffer
   * will be prepared for DMA and a suitable end_io handler set up.
   */
  int bio_integrity_prep(struct bio *bio)
  {
  	struct bio_integrity_payload *bip;
  	struct blk_integrity *bi;
  	struct request_queue *q;
  	void *buf;
  	unsigned long start, end;
  	unsigned int len, nr_pages;
  	unsigned int bytes, offset, i;
3be91c4a3   Martin K. Petersen   block: Deprecate ...
258
  	unsigned int intervals;
7ba1ba12e   Martin K. Petersen   block: Block laye...
259
260
261
262
263
  
  	bi = bdev_get_integrity(bio->bi_bdev);
  	q = bdev_get_queue(bio->bi_bdev);
  	BUG_ON(bi == NULL);
  	BUG_ON(bio_integrity(bio));
3be91c4a3   Martin K. Petersen   block: Deprecate ...
264
  	intervals = bio_integrity_intervals(bi, bio_sectors(bio));
7ba1ba12e   Martin K. Petersen   block: Block laye...
265
266
  
  	/* Allocate kernel buffer for protection data */
3be91c4a3   Martin K. Petersen   block: Deprecate ...
267
  	len = intervals * bi->tuple_size;
72f465033   David Rientjes   bio-integrity.c: ...
268
  	buf = kmalloc(len, GFP_NOIO | q->bounce_gfp);
7ba1ba12e   Martin K. Petersen   block: Block laye...
269
270
271
  	if (unlikely(buf == NULL)) {
  		printk(KERN_ERR "could not allocate integrity buffer
  ");
220eb7fd9   Andrew Morton   fs/bio-integrity....
272
  		return -ENOMEM;
7ba1ba12e   Martin K. Petersen   block: Block laye...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  	}
  
  	end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
  	start = ((unsigned long) buf) >> PAGE_SHIFT;
  	nr_pages = end - start;
  
  	/* Allocate bio integrity payload and integrity vectors */
  	bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
  	if (unlikely(bip == NULL)) {
  		printk(KERN_ERR "could not allocate data integrity bioset
  ");
  		kfree(buf);
  		return -EIO;
  	}
b1f013885   Martin K. Petersen   block: Relocate b...
287
  	bip->bip_flags |= BIP_BLOCK_INTEGRITY;
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
288
  	bip->bip_iter.bi_size = len;
185930885   Martin K. Petersen   block: Clean up t...
289
  	bip_set_seed(bip, bio->bi_iter.bi_sector);
7ba1ba12e   Martin K. Petersen   block: Block laye...
290

aae7df501   Martin K. Petersen   block: Integrity ...
291
292
  	if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
  		bip->bip_flags |= BIP_IP_CHECKSUM;
7ba1ba12e   Martin K. Petersen   block: Block laye...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  	/* Map it */
  	offset = offset_in_page(buf);
  	for (i = 0 ; i < nr_pages ; i++) {
  		int ret;
  		bytes = PAGE_SIZE - offset;
  
  		if (len <= 0)
  			break;
  
  		if (bytes > len)
  			bytes = len;
  
  		ret = bio_integrity_add_page(bio, virt_to_page(buf),
  					     bytes, offset);
  
  		if (ret == 0)
  			return 0;
  
  		if (ret < bytes)
  			break;
  
  		buf += bytes;
  		len -= bytes;
  		offset = 0;
  	}
  
  	/* Install custom I/O completion handler if read verify is enabled */
  	if (bio_data_dir(bio) == READ) {
  		bip->bip_end_io = bio->bi_end_io;
  		bio->bi_end_io = bio_integrity_endio;
  	}
  
  	/* Auto-generate integrity metadata if this is a write */
  	if (bio_data_dir(bio) == WRITE)
185930885   Martin K. Petersen   block: Clean up t...
327
  		bio_integrity_process(bio, bi->generate_fn);
7ba1ba12e   Martin K. Petersen   block: Block laye...
328
329
330
331
332
333
  
  	return 0;
  }
  EXPORT_SYMBOL(bio_integrity_prep);
  
  /**
7ba1ba12e   Martin K. Petersen   block: Block laye...
334
335
336
337
338
339
340
341
342
   * bio_integrity_verify_fn - Integrity I/O completion worker
   * @work:	Work struct stored in bio to be verified
   *
   * Description: This workqueue function is called to complete a READ
   * request.  The function verifies the transferred integrity metadata
   * and then calls the original bio end_io function.
   */
  static void bio_integrity_verify_fn(struct work_struct *work)
  {
b984679ef   Jens Axboe   block: integrity ...
343
  	struct bio_integrity_payload *bip =
7ba1ba12e   Martin K. Petersen   block: Block laye...
344
345
  		container_of(work, struct bio_integrity_payload, bip_work);
  	struct bio *bio = bip->bip_bio;
185930885   Martin K. Petersen   block: Clean up t...
346
  	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
7b24fc4d7   Martin K. Petersen   block: Don't veri...
347
  	int error;
7ba1ba12e   Martin K. Petersen   block: Block laye...
348

185930885   Martin K. Petersen   block: Clean up t...
349
  	error = bio_integrity_process(bio, bi->verify_fn);
7ba1ba12e   Martin K. Petersen   block: Block laye...
350
351
352
  
  	/* Restore original bio completion handler */
  	bio->bi_end_io = bip->bip_end_io;
196d38bcc   Kent Overstreet   block: Generic bi...
353
  	bio_endio_nodec(bio, error);
7ba1ba12e   Martin K. Petersen   block: Block laye...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  }
  
  /**
   * bio_integrity_endio - Integrity I/O completion function
   * @bio:	Protected bio
   * @error:	Pointer to errno
   *
   * Description: Completion for integrity I/O
   *
   * Normally I/O completion is done in interrupt context.  However,
   * verifying I/O integrity is a time-consuming task which must be run
   * in process context.	This function postpones completion
   * accordingly.
   */
  void bio_integrity_endio(struct bio *bio, int error)
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
370
  	struct bio_integrity_payload *bip = bio_integrity(bio);
7ba1ba12e   Martin K. Petersen   block: Block laye...
371
372
  
  	BUG_ON(bip->bip_bio != bio);
7b24fc4d7   Martin K. Petersen   block: Don't veri...
373
374
375
376
377
378
  	/* In case of an I/O error there is no point in verifying the
  	 * integrity metadata.  Restore original bio end_io handler
  	 * and run it.
  	 */
  	if (error) {
  		bio->bi_end_io = bip->bip_end_io;
16f408dc6   Sagi Grimberg   block: Fix BUG_ON...
379
  		bio_endio_nodec(bio, error);
7b24fc4d7   Martin K. Petersen   block: Don't veri...
380
381
382
  
  		return;
  	}
7ba1ba12e   Martin K. Petersen   block: Block laye...
383
384
385
386
387
388
  	INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
  	queue_work(kintegrityd_wq, &bip->bip_work);
  }
  EXPORT_SYMBOL(bio_integrity_endio);
  
  /**
7ba1ba12e   Martin K. Petersen   block: Block laye...
389
390
391
392
393
394
395
396
397
398
   * bio_integrity_advance - Advance integrity vector
   * @bio:	bio whose integrity vector to update
   * @bytes_done:	number of data bytes that have been completed
   *
   * Description: This function calculates how many integrity bytes the
   * number of completed data bytes correspond to and advances the
   * integrity vector accordingly.
   */
  void bio_integrity_advance(struct bio *bio, unsigned int bytes_done)
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
399
  	struct bio_integrity_payload *bip = bio_integrity(bio);
7ba1ba12e   Martin K. Petersen   block: Block laye...
400
  	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
401
  	unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
7ba1ba12e   Martin K. Petersen   block: Block laye...
402

d57a5f7c6   Kent Overstreet   bio-integrity: Co...
403
  	bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
7ba1ba12e   Martin K. Petersen   block: Block laye...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
  }
  EXPORT_SYMBOL(bio_integrity_advance);
  
  /**
   * bio_integrity_trim - Trim integrity vector
   * @bio:	bio whose integrity vector to update
   * @offset:	offset to first data sector
   * @sectors:	number of data sectors
   *
   * Description: Used to trim the integrity vector in a cloned bio.
   * The ivec will be advanced corresponding to 'offset' data sectors
   * and the length will be truncated corresponding to 'len' data
   * sectors.
   */
b984679ef   Jens Axboe   block: integrity ...
418
419
  void bio_integrity_trim(struct bio *bio, unsigned int offset,
  			unsigned int sectors)
7ba1ba12e   Martin K. Petersen   block: Block laye...
420
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
421
  	struct bio_integrity_payload *bip = bio_integrity(bio);
7ba1ba12e   Martin K. Petersen   block: Block laye...
422
  	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
7ba1ba12e   Martin K. Petersen   block: Block laye...
423

d57a5f7c6   Kent Overstreet   bio-integrity: Co...
424
425
  	bio_integrity_advance(bio, offset << 9);
  	bip->bip_iter.bi_size = bio_integrity_bytes(bi, sectors);
7ba1ba12e   Martin K. Petersen   block: Block laye...
426
427
428
429
  }
  EXPORT_SYMBOL(bio_integrity_trim);
  
  /**
7ba1ba12e   Martin K. Petersen   block: Block laye...
430
431
432
   * bio_integrity_clone - Callback for cloning bios with integrity metadata
   * @bio:	New bio
   * @bio_src:	Original bio
87092698c   un'ichi Nomura   block: Add gfp_ma...
433
   * @gfp_mask:	Memory allocation mask
7ba1ba12e   Martin K. Petersen   block: Block laye...
434
435
436
   *
   * Description:	Called to allocate a bip when cloning a bio
   */
7878cba9f   Martin K. Petersen   block: Create bip...
437
  int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
438
  			gfp_t gfp_mask)
7ba1ba12e   Martin K. Petersen   block: Block laye...
439
  {
180b2f95d   Martin K. Petersen   block: Replace bi...
440
  	struct bio_integrity_payload *bip_src = bio_integrity(bio_src);
7ba1ba12e   Martin K. Petersen   block: Block laye...
441
442
443
  	struct bio_integrity_payload *bip;
  
  	BUG_ON(bip_src == NULL);
1e2a410ff   Kent Overstreet   block: Ues bi_poo...
444
  	bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
7ba1ba12e   Martin K. Petersen   block: Block laye...
445
446
447
448
449
450
  
  	if (bip == NULL)
  		return -EIO;
  
  	memcpy(bip->bip_vec, bip_src->bip_vec,
  	       bip_src->bip_vcnt * sizeof(struct bio_vec));
7ba1ba12e   Martin K. Petersen   block: Block laye...
451
  	bip->bip_vcnt = bip_src->bip_vcnt;
d57a5f7c6   Kent Overstreet   bio-integrity: Co...
452
  	bip->bip_iter = bip_src->bip_iter;
7ba1ba12e   Martin K. Petersen   block: Block laye...
453
454
455
456
  
  	return 0;
  }
  EXPORT_SYMBOL(bio_integrity_clone);
7878cba9f   Martin K. Petersen   block: Create bip...
457
  int bioset_integrity_create(struct bio_set *bs, int pool_size)
7ba1ba12e   Martin K. Petersen   block: Block laye...
458
  {
a91a2785b   Martin K. Petersen   block: Require su...
459
460
  	if (bs->bio_integrity_pool)
  		return 0;
9f060e223   Kent Overstreet   block: Convert in...
461
  	bs->bio_integrity_pool = mempool_create_slab_pool(pool_size, bip_slab);
bc5c8f078   Gu Zheng   fs/bio-integrity:...
462
  	if (!bs->bio_integrity_pool)
9f060e223   Kent Overstreet   block: Convert in...
463
  		return -1;
7ba1ba12e   Martin K. Petersen   block: Block laye...
464

a6c39cb4f   Fabian Frederick   fs/bio: remove bs...
465
  	bs->bvec_integrity_pool = biovec_create_pool(pool_size);
bc5c8f078   Gu Zheng   fs/bio-integrity:...
466
467
  	if (!bs->bvec_integrity_pool) {
  		mempool_destroy(bs->bio_integrity_pool);
7878cba9f   Martin K. Petersen   block: Create bip...
468
  		return -1;
bc5c8f078   Gu Zheng   fs/bio-integrity:...
469
  	}
7878cba9f   Martin K. Petersen   block: Create bip...
470
471
472
473
474
475
476
477
478
  
  	return 0;
  }
  EXPORT_SYMBOL(bioset_integrity_create);
  
  void bioset_integrity_free(struct bio_set *bs)
  {
  	if (bs->bio_integrity_pool)
  		mempool_destroy(bs->bio_integrity_pool);
9f060e223   Kent Overstreet   block: Convert in...
479
480
  
  	if (bs->bvec_integrity_pool)
adbe6991e   Bjorn Helgaas   bio-integrity: Fi...
481
  		mempool_destroy(bs->bvec_integrity_pool);
7878cba9f   Martin K. Petersen   block: Create bip...
482
483
484
485
486
  }
  EXPORT_SYMBOL(bioset_integrity_free);
  
  void __init bio_integrity_init(void)
  {
a6e8dc46f   Tejun Heo   bio-integrity: ma...
487
488
489
490
491
492
  	/*
  	 * kintegrityd won't block much but may burn a lot of CPU cycles.
  	 * Make it highpri CPU intensive wq with max concurrency of 1.
  	 */
  	kintegrityd_wq = alloc_workqueue("kintegrityd", WQ_MEM_RECLAIM |
  					 WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
6d2a78e78   Martin K. Petersen   block: add privat...
493
494
495
  	if (!kintegrityd_wq)
  		panic("Failed to create kintegrityd
  ");
7ba1ba12e   Martin K. Petersen   block: Block laye...
496

9f060e223   Kent Overstreet   block: Convert in...
497
498
499
500
  	bip_slab = kmem_cache_create("bio_integrity_payload",
  				     sizeof(struct bio_integrity_payload) +
  				     sizeof(struct bio_vec) * BIP_INLINE_VECS,
  				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
7ba1ba12e   Martin K. Petersen   block: Block laye...
501
  }