Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2455306pxj; Mon, 10 May 2021 03:28:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyhxj1Sp+xyg6v1GcyjDiMgXTRvZ1eKb5nUH5vvuAAfDeEgyGqAyC4nubHuBqHZfo28Evsq X-Received: by 2002:a5d:9917:: with SMTP id x23mr17475303iol.22.1620642514783; Mon, 10 May 2021 03:28:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620642514; cv=none; d=google.com; s=arc-20160816; b=PEO9lCoRYK52QBO6YIWk+aCJkpTGi7H/xq076qtIKKuHUTmho5gteGPLHFRnCTV8Q9 SrJ+JIMybGhMeV+fFqxDdfHbg6J7AL+OaR8C5XH5fNrM768aq7LqGAU7TWxvL8bc/Znw KDUYCeXBSMg+2KVwW7TffxQulGXiLyfWOj9P1rMI1rO7JC75QA2f8kswQ+k8wyJ1ZPTI SztxhgLD36Jv/ZP0iducQQh80qHg0vRqkciMBKt55Bd9qQmQLnJJK8Crvz90+Tsk1gUj S5k6Y4SL/mwRF6NPMiXVG8VGhwcTe+SPzGYrcDludpNwcuZ4eHXTUHnI8mgbeEtYIGqS b59w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=s+yT9DTwj5zFmjuOV0DFcnXRdS4lfG0zOmcrnFJWcVY=; b=KJZ2nXdGLxAY3wqvNhEOudsYfUyz/A0H+5r0kehxmQSzY2vbVCSbUEv1Muk2vzf7zx fqU8dRuBSmgOf87uq2VclXTlqdk6IEryXPn0Hc2Vq5eYzPp/lTBeZUsVbOocTquVg6pV xe3LAwCJFUFDjrh8z+UKF1mR0+/mHFwh4xQZoYTAp2Eft7wnwsi5Y1KP4pQbqHwKFjnZ pNOt9vSr0Ny+gRN6Q0xnIAIzK14Xt/599JD7xxzYBGQstfTh98JL50vpQ4j2lUEXwxRR 45Lu2ck+vyymzdlabexZTZzZNiStPgf4Y9yORY7U4KBVCT5pDX5mSFYRPeRwjV6W1GGw 9sNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=xSp4fXdR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j6si2551622ilr.104.2021.05.10.03.28.22; Mon, 10 May 2021 03:28:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=xSp4fXdR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231538AbhEJK04 (ORCPT + 99 others); Mon, 10 May 2021 06:26:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:58262 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230381AbhEJK0D (ORCPT ); Mon, 10 May 2021 06:26:03 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7090561469; Mon, 10 May 2021 10:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620642289; bh=VrwHoIf2G4TvsPc3j/CElybg0GVSiEhd0AMv7J0lRnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xSp4fXdRJI27z73T9UidvIwARgAtTCqNSdLF2NbQiTfxtNevLuDvk7Zhxu3J7JKV7 Gdtxj7K1Md68W1MA5NZDkkWWYo4dSYq5BIuyouzBm3333Y7corUPBQ8NUYQ16dG2Lz 1ktI+deMi4K2ocUjly2zWuSm8YiopOwyZ+HDsWqI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Filipe Manana , David Sterba Subject: [PATCH 5.4 034/184] btrfs: fix metadata extent leak after failure to create subvolume Date: Mon, 10 May 2021 12:18:48 +0200 Message-Id: <20210510101951.340474920@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210510101950.200777181@linuxfoundation.org> References: <20210510101950.200777181@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Filipe Manana commit 67addf29004c5be9fa0383c82a364bb59afc7f84 upstream. When creating a subvolume we allocate an extent buffer for its root node after starting a transaction. We setup a root item for the subvolume that points to that extent buffer and then attempt to insert the root item into the root tree - however if that fails, due to ENOMEM for example, we do not free the extent buffer previously allocated and we do not abort the transaction (as at that point we did nothing that can not be undone). This means that we effectively do not return the metadata extent back to the free space cache/tree and we leave a delayed reference for it which causes a metadata extent item to be added to the extent tree, in the next transaction commit, without having backreferences. When this happens 'btrfs check' reports the following: $ btrfs check /dev/sdi Opening filesystem to check... Checking filesystem on /dev/sdi UUID: dce2cb9d-025f-4b05-a4bf-cee0ad3785eb [1/7] checking root items [2/7] checking extents ref mismatch on [30425088 16384] extent item 1, found 0 backref 30425088 root 256 not referenced back 0x564a91c23d70 incorrect global backref count on 30425088 found 1 wanted 0 backpointer mismatch on [30425088 16384] owner ref check failed [30425088 16384] ERROR: errors found in extent allocation tree or chunk allocation [3/7] checking free space cache [4/7] checking fs roots [5/7] checking only csums items (without verifying data) [6/7] checking root refs [7/7] checking quota groups skipped (not enabled on this FS) found 212992 bytes used, error(s) found total csum bytes: 0 total tree bytes: 131072 total fs tree bytes: 32768 total extent tree bytes: 16384 btree space waste bytes: 124669 file data blocks allocated: 65536 referenced 65536 So fix this by freeing the metadata extent if btrfs_insert_root() returns an error. CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ioctl.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -667,8 +667,6 @@ static noinline int create_subvol(struct btrfs_set_root_otransid(root_item, trans->transid); btrfs_tree_unlock(leaf); - free_extent_buffer(leaf); - leaf = NULL; btrfs_set_root_dirid(root_item, new_dirid); @@ -677,8 +675,22 @@ static noinline int create_subvol(struct key.type = BTRFS_ROOT_ITEM_KEY; ret = btrfs_insert_root(trans, fs_info->tree_root, &key, root_item); - if (ret) + if (ret) { + /* + * Since we don't abort the transaction in this case, free the + * tree block so that we don't leak space and leave the + * filesystem in an inconsistent state (an extent item in the + * extent tree without backreferences). Also no need to have + * the tree block locked since it is not in any tree at this + * point, so no other task can find it and use it. + */ + btrfs_free_tree_block(trans, root, leaf, 0, 1); + free_extent_buffer(leaf); goto fail; + } + + free_extent_buffer(leaf); + leaf = NULL; key.offset = (u64)-1; new_root = btrfs_read_fs_root_no_name(fs_info, &key);