diff options
-rw-r--r-- | Documentation/block/data-integrity.txt | 6 | ||||
-rw-r--r-- | block/bio-integrity.c | 88 | ||||
-rw-r--r-- | block/blk-core.c | 5 | ||||
-rw-r--r-- | block/blk-mq.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/blk.c | 13 | ||||
-rw-r--r-- | drivers/nvdimm/btt.c | 13 | ||||
-rw-r--r-- | include/linux/bio.h | 12 |
7 files changed, 50 insertions, 91 deletions
diff --git a/Documentation/block/data-integrity.txt b/Documentation/block/data-integrity.txt index f56ec97f0d14..934c44ea0c57 100644 --- a/Documentation/block/data-integrity.txt +++ b/Documentation/block/data-integrity.txt | |||
@@ -192,7 +192,7 @@ will require extra work due to the application tag. | |||
192 | supported by the block device. | 192 | supported by the block device. |
193 | 193 | ||
194 | 194 | ||
195 | int bio_integrity_prep(bio); | 195 | bool bio_integrity_prep(bio); |
196 | 196 | ||
197 | To generate IMD for WRITE and to set up buffers for READ, the | 197 | To generate IMD for WRITE and to set up buffers for READ, the |
198 | filesystem must call bio_integrity_prep(bio). | 198 | filesystem must call bio_integrity_prep(bio). |
@@ -201,9 +201,7 @@ will require extra work due to the application tag. | |||
201 | sector must be set, and the bio should have all data pages | 201 | sector must be set, and the bio should have all data pages |
202 | added. It is up to the caller to ensure that the bio does not | 202 | added. It is up to the caller to ensure that the bio does not |
203 | change while I/O is in progress. | 203 | change while I/O is in progress. |
204 | 204 | Complete bio with error if prepare failed for some reson. | |
205 | bio_integrity_prep() should only be called if | ||
206 | bio_integrity_enabled() returned 1. | ||
207 | 205 | ||
208 | 206 | ||
209 | 5.3 PASSING EXISTING INTEGRITY METADATA | 207 | 5.3 PASSING EXISTING INTEGRITY METADATA |
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 3a0d71199fb0..44c4c52681c2 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c | |||
@@ -160,44 +160,6 @@ int bio_integrity_add_page(struct bio *bio, struct page *page, | |||
160 | EXPORT_SYMBOL(bio_integrity_add_page); | 160 | EXPORT_SYMBOL(bio_integrity_add_page); |
161 | 161 | ||
162 | /** | 162 | /** |
163 | * bio_integrity_enabled - Check whether integrity can be passed | ||
164 | * @bio: bio to check | ||
165 | * | ||
166 | * Description: Determines whether bio_integrity_prep() can be called | ||
167 | * on this bio or not. bio data direction and target device must be | ||
168 | * set prior to calling. The functions honors the write_generate and | ||
169 | * read_verify flags in sysfs. | ||
170 | */ | ||
171 | bool bio_integrity_enabled(struct bio *bio) | ||
172 | { | ||
173 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | ||
174 | |||
175 | if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE) | ||
176 | return false; | ||
177 | |||
178 | if (!bio_sectors(bio)) | ||
179 | return false; | ||
180 | |||
181 | /* Already protected? */ | ||
182 | if (bio_integrity(bio)) | ||
183 | return false; | ||
184 | |||
185 | if (bi == NULL) | ||
186 | return false; | ||
187 | |||
188 | if (bio_data_dir(bio) == READ && bi->profile->verify_fn != NULL && | ||
189 | (bi->flags & BLK_INTEGRITY_VERIFY)) | ||
190 | return true; | ||
191 | |||
192 | if (bio_data_dir(bio) == WRITE && bi->profile->generate_fn != NULL && | ||
193 | (bi->flags & BLK_INTEGRITY_GENERATE)) | ||
194 | return true; | ||
195 | |||
196 | return false; | ||
197 | } | ||
198 | EXPORT_SYMBOL(bio_integrity_enabled); | ||
199 | |||
200 | /** | ||
201 | * bio_integrity_intervals - Return number of integrity intervals for a bio | 163 | * bio_integrity_intervals - Return number of integrity intervals for a bio |
202 | * @bi: blk_integrity profile for device | 164 | * @bi: blk_integrity profile for device |
203 | * @sectors: Size of the bio in 512-byte sectors | 165 | * @sectors: Size of the bio in 512-byte sectors |
@@ -262,14 +224,15 @@ static blk_status_t bio_integrity_process(struct bio *bio, | |||
262 | * bio_integrity_prep - Prepare bio for integrity I/O | 224 | * bio_integrity_prep - Prepare bio for integrity I/O |
263 | * @bio: bio to prepare | 225 | * @bio: bio to prepare |
264 | * | 226 | * |
265 | * Description: Allocates a buffer for integrity metadata, maps the | 227 | * Description: Checks if the bio already has an integrity payload attached. |
266 | * pages and attaches them to a bio. The bio must have data | 228 | * If it does, the payload has been generated by another kernel subsystem, |
267 | * direction, target device and start sector set priot to calling. In | 229 | * and we just pass it through. Otherwise allocates integrity payload. |
268 | * the WRITE case, integrity metadata will be generated using the | 230 | * The bio must have data direction, target device and start sector set priot |
269 | * block device's integrity function. In the READ case, the buffer | 231 | * to calling. In the WRITE case, integrity metadata will be generated using |
232 | * the block device's integrity function. In the READ case, the buffer | ||
270 | * will be prepared for DMA and a suitable end_io handler set up. | 233 | * will be prepared for DMA and a suitable end_io handler set up. |
271 | */ | 234 | */ |
272 | int bio_integrity_prep(struct bio *bio) | 235 | bool bio_integrity_prep(struct bio *bio) |
273 | { | 236 | { |
274 | struct bio_integrity_payload *bip; | 237 | struct bio_integrity_payload *bip; |
275 | struct blk_integrity *bi; | 238 | struct blk_integrity *bi; |
@@ -279,20 +242,41 @@ int bio_integrity_prep(struct bio *bio) | |||
279 | unsigned int len, nr_pages; | 242 | unsigned int len, nr_pages; |
280 | unsigned int bytes, offset, i; | 243 | unsigned int bytes, offset, i; |
281 | unsigned int intervals; | 244 | unsigned int intervals; |
245 | blk_status_t status; | ||
282 | 246 | ||
283 | bi = bdev_get_integrity(bio->bi_bdev); | 247 | bi = bdev_get_integrity(bio->bi_bdev); |
284 | q = bdev_get_queue(bio->bi_bdev); | 248 | q = bdev_get_queue(bio->bi_bdev); |
285 | BUG_ON(bi == NULL); | 249 | if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE) |
286 | BUG_ON(bio_integrity(bio)); | 250 | return true; |
251 | |||
252 | if (!bio_sectors(bio)) | ||
253 | return true; | ||
287 | 254 | ||
255 | /* Already protected? */ | ||
256 | if (bio_integrity(bio)) | ||
257 | return true; | ||
258 | |||
259 | if (bi == NULL) | ||
260 | return true; | ||
261 | |||
262 | if (bio_data_dir(bio) == READ) { | ||
263 | if (!bi->profile->verify_fn || | ||
264 | !(bi->flags & BLK_INTEGRITY_VERIFY)) | ||
265 | return true; | ||
266 | } else { | ||
267 | if (!bi->profile->generate_fn || | ||
268 | !(bi->flags & BLK_INTEGRITY_GENERATE)) | ||
269 | return true; | ||
270 | } | ||
288 | intervals = bio_integrity_intervals(bi, bio_sectors(bio)); | 271 | intervals = bio_integrity_intervals(bi, bio_sectors(bio)); |
289 | 272 | ||
290 | /* Allocate kernel buffer for protection data */ | 273 | /* Allocate kernel buffer for protection data */ |
291 | len = intervals * bi->tuple_size; | 274 | len = intervals * bi->tuple_size; |
292 | buf = kmalloc(len, GFP_NOIO | q->bounce_gfp); | 275 | buf = kmalloc(len, GFP_NOIO | q->bounce_gfp); |
276 | status = BLK_STS_RESOURCE; | ||
293 | if (unlikely(buf == NULL)) { | 277 | if (unlikely(buf == NULL)) { |
294 | printk(KERN_ERR "could not allocate integrity buffer\n"); | 278 | printk(KERN_ERR "could not allocate integrity buffer\n"); |
295 | return -ENOMEM; | 279 | goto err_end_io; |
296 | } | 280 | } |
297 | 281 | ||
298 | end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 282 | end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
@@ -304,7 +288,8 @@ int bio_integrity_prep(struct bio *bio) | |||
304 | if (IS_ERR(bip)) { | 288 | if (IS_ERR(bip)) { |
305 | printk(KERN_ERR "could not allocate data integrity bioset\n"); | 289 | printk(KERN_ERR "could not allocate data integrity bioset\n"); |
306 | kfree(buf); | 290 | kfree(buf); |
307 | return PTR_ERR(bip); | 291 | status = BLK_STS_RESOURCE; |
292 | goto err_end_io; | ||
308 | } | 293 | } |
309 | 294 | ||
310 | bip->bip_flags |= BIP_BLOCK_INTEGRITY; | 295 | bip->bip_flags |= BIP_BLOCK_INTEGRITY; |
@@ -349,8 +334,13 @@ int bio_integrity_prep(struct bio *bio) | |||
349 | /* Auto-generate integrity metadata if this is a write */ | 334 | /* Auto-generate integrity metadata if this is a write */ |
350 | if (bio_data_dir(bio) == WRITE) | 335 | if (bio_data_dir(bio) == WRITE) |
351 | bio_integrity_process(bio, bi->profile->generate_fn); | 336 | bio_integrity_process(bio, bi->profile->generate_fn); |
337 | return true; | ||
338 | |||
339 | err_end_io: | ||
340 | bio->bi_status = status; | ||
341 | bio_endio(bio); | ||
342 | return false; | ||
352 | 343 | ||
353 | return 0; | ||
354 | } | 344 | } |
355 | EXPORT_SYMBOL(bio_integrity_prep); | 345 | EXPORT_SYMBOL(bio_integrity_prep); |
356 | 346 | ||
diff --git a/block/blk-core.c b/block/blk-core.c index af393d5a9680..970b9c9638c5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1787,11 +1787,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio) | |||
1787 | 1787 | ||
1788 | blk_queue_split(q, &bio); | 1788 | blk_queue_split(q, &bio); |
1789 | 1789 | ||
1790 | if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { | 1790 | if (!bio_integrity_prep(bio)) |
1791 | bio->bi_status = BLK_STS_IOERR; | ||
1792 | bio_endio(bio); | ||
1793 | return BLK_QC_T_NONE; | 1791 | return BLK_QC_T_NONE; |
1794 | } | ||
1795 | 1792 | ||
1796 | if (op_is_flush(bio->bi_opf)) { | 1793 | if (op_is_flush(bio->bi_opf)) { |
1797 | spin_lock_irq(q->queue_lock); | 1794 | spin_lock_irq(q->queue_lock); |
diff --git a/block/blk-mq.c b/block/blk-mq.c index ced2b000ca02..77617fb12661 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -1550,10 +1550,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) | |||
1550 | 1550 | ||
1551 | blk_queue_split(q, &bio); | 1551 | blk_queue_split(q, &bio); |
1552 | 1552 | ||
1553 | if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { | 1553 | if (!bio_integrity_prep(bio)) |
1554 | bio_io_error(bio); | ||
1555 | return BLK_QC_T_NONE; | 1554 | return BLK_QC_T_NONE; |
1556 | } | ||
1557 | 1555 | ||
1558 | if (!is_flush_fua && !blk_queue_nomerges(q) && | 1556 | if (!is_flush_fua && !blk_queue_nomerges(q) && |
1559 | blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq)) | 1557 | blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq)) |
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c index f12d23c49771..1a578b2a437b 100644 --- a/drivers/nvdimm/blk.c +++ b/drivers/nvdimm/blk.c | |||
@@ -179,16 +179,8 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio) | |||
179 | int err = 0, rw; | 179 | int err = 0, rw; |
180 | bool do_acct; | 180 | bool do_acct; |
181 | 181 | ||
182 | /* | 182 | if (!bio_integrity_prep(bio)) |
183 | * bio_integrity_enabled also checks if the bio already has an | 183 | return BLK_QC_T_NONE; |
184 | * integrity payload attached. If it does, we *don't* do a | ||
185 | * bio_integrity_prep here - the payload has been generated by | ||
186 | * another kernel subsystem, and we just pass it through. | ||
187 | */ | ||
188 | if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { | ||
189 | bio->bi_status = BLK_STS_IOERR; | ||
190 | goto out; | ||
191 | } | ||
192 | 184 | ||
193 | bip = bio_integrity(bio); | 185 | bip = bio_integrity(bio); |
194 | nsblk = q->queuedata; | 186 | nsblk = q->queuedata; |
@@ -212,7 +204,6 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio) | |||
212 | if (do_acct) | 204 | if (do_acct) |
213 | nd_iostat_end(bio, start); | 205 | nd_iostat_end(bio, start); |
214 | 206 | ||
215 | out: | ||
216 | bio_endio(bio); | 207 | bio_endio(bio); |
217 | return BLK_QC_T_NONE; | 208 | return BLK_QC_T_NONE; |
218 | } | 209 | } |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index b6ba0618ea46..b5caaee78bbf 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
@@ -1203,16 +1203,8 @@ static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio) | |||
1203 | int err = 0; | 1203 | int err = 0; |
1204 | bool do_acct; | 1204 | bool do_acct; |
1205 | 1205 | ||
1206 | /* | 1206 | if (!bio_integrity_prep(bio)) |
1207 | * bio_integrity_enabled also checks if the bio already has an | 1207 | return BLK_QC_T_NONE; |
1208 | * integrity payload attached. If it does, we *don't* do a | ||
1209 | * bio_integrity_prep here - the payload has been generated by | ||
1210 | * another kernel subsystem, and we just pass it through. | ||
1211 | */ | ||
1212 | if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { | ||
1213 | bio->bi_status = BLK_STS_IOERR; | ||
1214 | goto out; | ||
1215 | } | ||
1216 | 1208 | ||
1217 | do_acct = nd_iostat_start(bio, &start); | 1209 | do_acct = nd_iostat_start(bio, &start); |
1218 | bio_for_each_segment(bvec, bio, iter) { | 1210 | bio_for_each_segment(bvec, bio, iter) { |
@@ -1239,7 +1231,6 @@ static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio) | |||
1239 | if (do_acct) | 1231 | if (do_acct) |
1240 | nd_iostat_end(bio, start); | 1232 | nd_iostat_end(bio, start); |
1241 | 1233 | ||
1242 | out: | ||
1243 | bio_endio(bio); | 1234 | bio_endio(bio); |
1244 | return BLK_QC_T_NONE; | 1235 | return BLK_QC_T_NONE; |
1245 | } | 1236 | } |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 1d74f5120369..b3b5f5a89a9c 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -724,8 +724,7 @@ struct biovec_slab { | |||
724 | extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); | 724 | extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); |
725 | extern void bio_integrity_free(struct bio *); | 725 | extern void bio_integrity_free(struct bio *); |
726 | extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); | 726 | extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int); |
727 | extern bool bio_integrity_enabled(struct bio *bio); | 727 | extern bool bio_integrity_prep(struct bio *); |
728 | extern int bio_integrity_prep(struct bio *); | ||
729 | extern void bio_integrity_endio(struct bio *); | 728 | extern void bio_integrity_endio(struct bio *); |
730 | extern void bio_integrity_advance(struct bio *, unsigned int); | 729 | extern void bio_integrity_advance(struct bio *, unsigned int); |
731 | extern void bio_integrity_trim(struct bio *); | 730 | extern void bio_integrity_trim(struct bio *); |
@@ -741,11 +740,6 @@ static inline void *bio_integrity(struct bio *bio) | |||
741 | return NULL; | 740 | return NULL; |
742 | } | 741 | } |
743 | 742 | ||
744 | static inline bool bio_integrity_enabled(struct bio *bio) | ||
745 | { | ||
746 | return false; | ||
747 | } | ||
748 | |||
749 | static inline int bioset_integrity_create(struct bio_set *bs, int pool_size) | 743 | static inline int bioset_integrity_create(struct bio_set *bs, int pool_size) |
750 | { | 744 | { |
751 | return 0; | 745 | return 0; |
@@ -756,9 +750,9 @@ static inline void bioset_integrity_free (struct bio_set *bs) | |||
756 | return; | 750 | return; |
757 | } | 751 | } |
758 | 752 | ||
759 | static inline int bio_integrity_prep(struct bio *bio) | 753 | static inline bool bio_integrity_prep(struct bio *bio) |
760 | { | 754 | { |
761 | return 0; | 755 | return true; |
762 | } | 756 | } |
763 | 757 | ||
764 | static inline void bio_integrity_free(struct bio *bio) | 758 | static inline void bio_integrity_free(struct bio *bio) |