btrfs_repair_one_zone() hands the block group reference taken by btrfs_lookup_block_group() over to relocating_repair_kthread(), which drops it. However the return value of kthread_run() is not checked, so when the kernel thread fails to spawn, nothing executes the put and the block group reference is leaked. Check kthread_run() and drop the reference if the thread failed to start. Fixes: f7ef5287a63d ("btrfs: zoned: relocate block group to repair IO failure in zoned filesystems") Cc: stable@vger.kernel.org Signed-off-by: Wentao Liang --- fs/btrfs/volumes.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a88e68f90564..541bcd65a6f6 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -8770,6 +8770,7 @@ static int relocating_repair_kthread(void *data) bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical) { struct btrfs_block_group *cache; + struct task_struct *task; if (!btrfs_is_zoned(fs_info)) return false; @@ -8787,8 +8788,10 @@ bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical) return true; } - kthread_run(relocating_repair_kthread, cache, - "btrfs-relocating-repair"); + task = kthread_run(relocating_repair_kthread, cache, + "btrfs-relocating-repair"); + if (IS_ERR(task)) + btrfs_put_block_group(cache); return true; } -- 2.34.1