From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-bn3nam01on0104.outbound.protection.outlook.com ([104.47.33.104]:21664 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1032466AbeCAPfp (ORCPT ); Thu, 1 Mar 2018 10:35:45 -0500 From: Sasha Levin To: "stable@vger.kernel.org" , "stable-commits@vger.kernel.org" CC: Liu Bo , David Sterba , Sasha Levin Subject: [added to the 4.1 stable tree] Btrfs: fix crash due to not cleaning up tree log block's dirty bits Date: Thu, 1 Mar 2018 15:26:31 +0000 Message-ID: <20180301152116.1486-372-alexander.levin@microsoft.com> References: <20180301152116.1486-1-alexander.levin@microsoft.com> In-Reply-To: <20180301152116.1486-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Liu Bo This patch has been added to the 4.1 stable tree. If you have any objections, please let us know. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [ Upstream commit 1846430c24d66e85cc58286b3319c82cd54debb2 ] In cases that the whole fs flips into readonly status due to failures in critical sections, then log tree's blocks are still dirty, and this leads to a crash during umount time, the crash is about use-after-free, umount -> close_ctree -> stop workers -> iput(btree_inode) -> iput_final -> write_inode_now -> ... -> queue job on stop'd workers cc: v3.12+ Fixes: 681ae50917df ("Btrfs: cleanup reserved space when freeing tree log o= n error") Signed-off-by: Liu Bo Reviewed-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/tree-log.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6ee954c62fe6..3cd1abf692dd 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2343,6 +2343,9 @@ static noinline int walk_down_log_tree(struct btrfs_t= rans_handle *trans, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } =20 WARN_ON(root_owner !=3D @@ -2422,6 +2425,9 @@ static noinline int walk_up_log_tree(struct btrfs_tra= ns_handle *trans, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } =20 WARN_ON(root_owner !=3D BTRFS_TREE_LOG_OBJECTID); @@ -2498,6 +2504,9 @@ static int walk_log_tree(struct btrfs_trans_handle *t= rans, clean_tree_block(trans, log->fs_info, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } =20 WARN_ON(log->root_key.objectid !=3D --=20 2.14.1