summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2024-07-02 18:10:21 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-09-12 12:12:59 +0300
commit64149da0fddbbfe43e11c0348d8c8b4171dae3a2 (patch)
tree6978023ce38e1f55318917556e63a91452938919 /block
parent08205763198a7e04a1357b4c51ddeab80628da00 (diff)
downloadlinux-64149da0fddbbfe43e11c0348d8c8b4171dae3a2.tar.xz
block: don't call bio_uninit from bio_endio
[ Upstream commit bf4c89fc8797f5c0964a0c3d561fbe7e8483b62f ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'block')
-rw-r--r--block/bio.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/block/bio.c b/block/bio.c
index e9e809a63c59..c7a4bc05c43e 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);
}