diff options
author | Christoph Hellwig <hch@lst.de> | 2024-07-02 17:10:21 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-07-03 10:21:16 -0600 |
commit | bf4c89fc8797f5c0964a0c3d561fbe7e8483b62f (patch) | |
tree | 2b729defed51056385346fe4f3889288a7c4e3e0 /block | |
parent | 21671a1ed1ff22e158ebe9d619943f926f03f5cd (diff) |
block: don't call bio_uninit from bio_endio
Commit b222dd2fdd53 ("block: call bio_uninit in bio_endio") added a call
to bio_uninit in bio_endio to work around callers that use bio_init but
fail to call bio_uninit after they are done to release the resources.
While this is an abuse of the bio_init API we still have quite a few of
those left. But this early uninit causes a problem for integrity data,
as at least some users need the bio_integrity_payload. Right now the
only one is the NVMe passthrough which archives this by adding a special
case to skip the freeing if the BIP_INTEGRITY_USER flag is set.
Sort this out by only putting bi_blkg in bio_endio as that is the cause
of the actual leaks - the few users of the crypto context and integrity
data all properly call bio_uninit, usually through bio_put for
dynamically allocated bios.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20240702151047.1746127-4-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/block/bio.c b/block/bio.c index 4ca3f31ce45f..68ce75fd9b7c 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1630,8 +1630,18 @@ again: goto again; } - /* release cgroup info */ - bio_uninit(bio); +#ifdef CONFIG_BLK_CGROUP + /* + * Release cgroup info. We shouldn't have to do this here, but quite + * a few callers of bio_init fail to call bio_uninit, so we cover up + * for that here at least for now. + */ + if (bio->bi_blkg) { + blkg_put(bio->bi_blkg); + bio->bi_blkg = NULL; + } +#endif + if (bio->bi_end_io) bio->bi_end_io(bio); } |