From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A87FD31D389; Mon, 27 Oct 2025 19:09:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761592153; cv=none; b=RLl600Ga/EsObdzMRC+p7tamo1w8v51u+yQDxPODMKkfJT64DedzuxjY0YHfQy0Nx2x5z3LkbdcTcKy9gWt3l3AUKi98VeSiETH+rZ53/LYq8oKAjM5qvu2t8CyMK9Fk/xAWzVF/oMWerfBdBdhC/GNQ2CVXs1hZ4jnPFAIn/5E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761592153; c=relaxed/simple; bh=x3O3Z1SHf5YXLseKcXA5uVtVB0jXbDe9jH8KRkfRDUg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NEeFq0J8j7p6QtZt4vOVD9cR2sj2JAh81DreEBimjNSr2h6phaVFZMle5y3Uy3ae6gBhFnxUx6JfkW1CJn4nWATPSNJZ/EKyHA0rycsOXVlqRteXCIfC95NAr9+VZwTZhaUsKm1S5eM2UeMX7yCh2Pwa57ab8zPaj/r2f80STIc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=ps0+72fx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="ps0+72fx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E0AB6C113D0; Mon, 27 Oct 2025 19:09:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1761592153; bh=x3O3Z1SHf5YXLseKcXA5uVtVB0jXbDe9jH8KRkfRDUg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ps0+72fxydTFw2E/+3Mt5whqrs/XxNWBiTd/H2is4S23++jFZXar8pewTAkcK1SYH +soIkrrb5zCZAkB5k+1WwFAVTPtd245j6kxvfZ/JTZR061XVssp0SJOYOsUK3MgY92 m0y2nClOCKXuASFu3jVTIe6O4JRpMM3SlaEvm95U= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Boris Burkov , Johannes Thumshirn , Qu Wenruo , Filipe Manana , David Sterba Subject: [PATCH 6.1 006/157] btrfs: fix clearing of BTRFS_FS_RELOC_RUNNING if relocation already running Date: Mon, 27 Oct 2025 19:34:27 +0100 Message-ID: <20251027183501.411791682@linuxfoundation.org> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251027183501.227243846@linuxfoundation.org> References: <20251027183501.227243846@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Filipe Manana commit 7e5a5983edda664e8e4bb20af17b80f5135c655c upstream. When starting relocation, at reloc_chunk_start(), if we happen to find the flag BTRFS_FS_RELOC_RUNNING is already set we return an error (-EINPROGRESS) to the callers, however the callers call reloc_chunk_end() which will clear the flag BTRFS_FS_RELOC_RUNNING, which is wrong since relocation was started by another task and still running. Finding the BTRFS_FS_RELOC_RUNNING flag already set is an unexpected scenario, but still our current behaviour is not correct. Fix this by never calling reloc_chunk_end() if reloc_chunk_start() has returned an error, which is what logically makes sense, since the general widespread pattern is to have end functions called only if the counterpart start functions succeeded. This requires changing reloc_chunk_start() to clear BTRFS_FS_RELOC_RUNNING if there's a pending cancel request. Fixes: 907d2710d727 ("btrfs: add cancellable chunk relocation support") CC: stable@vger.kernel.org # 5.15+ Reviewed-by: Boris Burkov Reviewed-by: Johannes Thumshirn Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/relocation.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3915,6 +3915,7 @@ out: /* * Mark start of chunk relocation that is cancellable. Check if the cancellation * has been requested meanwhile and don't start in that case. + * NOTE: if this returns an error, reloc_chunk_end() must not be called. * * Return: * 0 success @@ -3931,10 +3932,8 @@ static int reloc_chunk_start(struct btrf if (atomic_read(&fs_info->reloc_cancel_req) > 0) { btrfs_info(fs_info, "chunk relocation canceled on start"); - /* - * On cancel, clear all requests but let the caller mark - * the end after cleanup operations. - */ + /* On cancel, clear all requests. */ + clear_and_wake_up_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags); atomic_set(&fs_info->reloc_cancel_req, 0); return -ECANCELED; } @@ -3943,9 +3942,11 @@ static int reloc_chunk_start(struct btrf /* * Mark end of chunk relocation that is cancellable and wake any waiters. + * NOTE: call only if a previous call to reloc_chunk_start() succeeded. */ static void reloc_chunk_end(struct btrfs_fs_info *fs_info) { + ASSERT(test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags)); /* Requested after start, clear bit first so any waiters can continue */ if (atomic_read(&fs_info->reloc_cancel_req) > 0) btrfs_info(fs_info, "chunk relocation canceled during operation"); @@ -4158,9 +4159,9 @@ out: if (err && rw) btrfs_dec_block_group_ro(rc->block_group); iput(rc->data_inode); + reloc_chunk_end(fs_info); out_put_bg: btrfs_put_block_group(bg); - reloc_chunk_end(fs_info); free_reloc_control(rc); return err; } @@ -4350,8 +4351,8 @@ out_clean: err = ret; out_unset: unset_reloc_control(rc); -out_end: reloc_chunk_end(fs_info); +out_end: free_reloc_control(rc); out: free_reloc_roots(&reloc_roots);