diff options
Diffstat (limited to 'block/bio-integrity.c')
-rw-r--r-- | block/bio-integrity.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 2e3e8e0496..741581a752 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -144,10 +144,10 @@ void bio_integrity_free(struct bio *bio) struct bio_integrity_payload *bip = bio_integrity(bio); struct bio_set *bs = bio->bi_pool; + if (bip->bip_flags & BIP_INTEGRITY_USER) + return; if (bip->bip_flags & BIP_BLOCK_INTEGRITY) kfree(bvec_virt(bip->bip_vec)); - else if (bip->bip_flags & BIP_INTEGRITY_USER) - bio_integrity_unmap_user(bip); __bio_integrity_free(bs, bip); bio->bi_integrity = NULL; @@ -155,6 +155,28 @@ void bio_integrity_free(struct bio *bio) } /** + * bio_integrity_unmap_free_user - Unmap and free bio user integrity payload + * @bio: bio containing bip to be unmapped and freed + * + * Description: Used to unmap and free the user mapped integrity portion of a + * bio. Submitter attaching the user integrity buffer is responsible for + * unmapping and freeing it during completion. + */ +void bio_integrity_unmap_free_user(struct bio *bio) +{ + struct bio_integrity_payload *bip = bio_integrity(bio); + struct bio_set *bs = bio->bi_pool; + + if (WARN_ON_ONCE(!(bip->bip_flags & BIP_INTEGRITY_USER))) + return; + bio_integrity_unmap_user(bip); + __bio_integrity_free(bs, bip); + bio->bi_integrity = NULL; + bio->bi_opf &= ~REQ_INTEGRITY; +} +EXPORT_SYMBOL(bio_integrity_unmap_free_user); + +/** * bio_integrity_add_page - Attach integrity metadata * @bio: bio to update * @page: page containing integrity metadata @@ -432,6 +454,7 @@ bool bio_integrity_prep(struct bio *bio) unsigned long start, end; unsigned int len, nr_pages; unsigned int bytes, offset, i; + gfp_t gfp = GFP_NOIO; if (!bi) return true; @@ -454,11 +477,19 @@ bool bio_integrity_prep(struct bio *bio) if (!bi->profile->generate_fn || !(bi->flags & BLK_INTEGRITY_GENERATE)) return true; + + /* + * Zero the memory allocated to not leak uninitialized kernel + * memory to disk. For PI this only affects the app tag, but + * for non-integrity metadata it affects the entire metadata + * buffer. + */ + gfp |= __GFP_ZERO; } /* Allocate kernel buffer for protection data */ len = bio_integrity_bytes(bi, bio_sectors(bio)); - buf = kmalloc(len, GFP_NOIO); + buf = kmalloc(len, gfp); if (unlikely(buf == NULL)) { printk(KERN_ERR "could not allocate integrity buffer\n"); goto err_end_io; |