Skip to content

Commit ccbc5d0

Browse files
Justin Teegregkh
authored andcommitted
block: fix memleak of bio integrity data
[ Upstream commit ece841a ] 7c20f11 ("bio-integrity: stop abusing bi_end_io") moves bio_integrity_free from bio_uninit() to bio_integrity_verify_fn() and bio_endio(). This way looks wrong because bio may be freed without calling bio_endio(), for example, blk_rq_unprep_clone() is called from dm_mq_queue_rq() when the underlying queue of dm-mpath is busy. So memory leak of bio integrity data is caused by commit 7c20f11. Fixes this issue by re-adding bio_integrity_free() to bio_uninit(). Fixes: 7c20f11 ("bio-integrity: stop abusing bi_end_io") Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by Justin Tee <justin.tee@broadcom.com> Add commit log, and simplify/fix the original patch wroten by Justin. Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 022321a commit ccbc5d0

3 files changed

Lines changed: 8 additions & 1 deletion

File tree

block/bio-integrity.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ EXPORT_SYMBOL(bio_integrity_alloc);
8787
* Description: Used to free the integrity portion of a bio. Usually
8888
* called from bio_free().
8989
*/
90-
static void bio_integrity_free(struct bio *bio)
90+
void bio_integrity_free(struct bio *bio)
9191
{
9292
struct bio_integrity_payload *bip = bio_integrity(bio);
9393
struct bio_set *bs = bio->bi_pool;

block/bio.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ struct bio_vec *bvec_alloc(gfp_t gfp_mask, int nr, unsigned long *idx,
233233
void bio_uninit(struct bio *bio)
234234
{
235235
bio_disassociate_blkg(bio);
236+
237+
if (bio_integrity(bio))
238+
bio_integrity_free(bio);
236239
}
237240
EXPORT_SYMBOL(bio_uninit);
238241

block/blk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ static inline void blk_rq_bio_prep(struct request *rq, struct bio *bio,
122122
#ifdef CONFIG_BLK_DEV_INTEGRITY
123123
void blk_flush_integrity(void);
124124
bool __bio_integrity_endio(struct bio *);
125+
void bio_integrity_free(struct bio *bio);
125126
static inline bool bio_integrity_endio(struct bio *bio)
126127
{
127128
if (bio_integrity(bio))
@@ -167,6 +168,9 @@ static inline bool bio_integrity_endio(struct bio *bio)
167168
{
168169
return true;
169170
}
171+
static inline void bio_integrity_free(struct bio *bio)
172+
{
173+
}
170174
#endif /* CONFIG_BLK_DEV_INTEGRITY */
171175

172176
unsigned long blk_rq_timeout(unsigned long timeout);

0 commit comments

Comments
 (0)