[PATCH v4 2/6] qnx6: release bh on error path in qnx6_block_map()
From: Hui Peng
Date: Tue Sep 29 2026 - 23:17:10 EST
In qnx6_block_map(), if qnx6_check_blockptr(ptr) returns false while
traversing indirect tree levels, the function returns 0 without calling
brelse(bh), leaking the allocated buffer head.
Call brelse(bh) before returning 0 on qnx6_check_blockptr() failure.
Tested in QEMU against tip of mainline commit 62f4c998b297 ("Merge tag 'parisc-for-7.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux")
using a loop-device reproducer reading a file whose indirect block
contains an invalid block pointer: on the unfixed kernel, check_bh_leaked()
detected indirect block 5's buffer_head leaked and pinned in page cache
(indirect_page5_leaked=1); whereas with this fix applied, brelse(bh) is
called on error and the buffer_head is cleanly evicted
(indirect_page5_leaked=0).
Fixes: 5d026c724220 ("fs: initial qnx6fs addition")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@xxxxxxxxx>
---
Changes in v4:
- Rebased cleanly onto upstream mainline commit 62f4c998b297.
- Added QEMU test procedure and verification details in commit message body.
fs/qnx6/inode.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index c999dcfdc477..080f7698a5e0 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -144,8 +144,10 @@ static unsigned qnx6_block_map(struct inode *inode, unsigned no)
levelptr = (no >> bitdelta) & mask;
ptr = ((__fs32 *)bh->b_data)[levelptr];
- if (!qnx6_check_blockptr(ptr))
- return 0;
+ if (!qnx6_check_blockptr(ptr)) {
+ brelse(bh);
+ return 0;
+ }
block = qnx6_get_devblock(s, ptr);
brelse(bh);
--
2.55.0.1082.g2b9226bbc0-goog