Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2472761pxj; Mon, 10 May 2021 03:57:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyHlrmbIc3twICj6K+uySLzX/FKxvu0yt+YR4+v/FAtbp3YUQrDATsojBPzpP2tFXAJgp4E X-Received: by 2002:a17:906:8307:: with SMTP id j7mr24253683ejx.420.1620644277130; Mon, 10 May 2021 03:57:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620644277; cv=none; d=google.com; s=arc-20160816; b=NwN5sXKlBlgsCkT20Et5k7GN20XgiFih2Obm+6ryg1qJFbswgBLddUQELWOt3J2lOT LfwOBpPSVV/Q+qfrVTPEqTgUBF3zmtkhOsFEBD3IQcNN3lCDCOPN357tgyuHUWoJIYL/ ndekkLdtRUm8RlOtJv57xFJ+dxa6Mzs/lUR6gg30EeTooJlUsk0RCuqAcQnhs8itooKi goapCN70epaNvs09Dx7yzDdLjhtkv89fpz4WVdRrDy+T7CPkH9neh62xTYwvAS16NzM+ r7cqO8IdrcgqhuKsFQXp2bJc6yCQw23hqD0QZH85EcEAxnbxJVtlvoWj/xHxciXZoT0r 6fHg== 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=IMd3peIleyenf19RdFt8YLS6XK71eYx9VV80XhMdB3k=; b=p5AOnTlY7sTBKUO99ia5oVZ8TRS0J6tEXHbIYPXD3sRXyJh/drhtGjkVwXczH6X6vt PEl6dbP/EhT+uRRSiFPpJwL57p7Ftz9NnalVgxkjoB/25GY61Bcey/meyByyll1K+GL9 1T62uQUHKqbjGiaZ2jhaAplJy6TRnt8Q+1vV2ReGe0pQTxfdpb1n/qRAIhGOSaSZxJCy 20VHeqnXXruBi3x8YA6b1+Lr60rcZEAGbBV8h3o1x7giQ6fPb6pWvMFkgBl1bLL+jxf6 CBtVqrtgIcuSUOKndc3M+yqiH8Gq/7TblicGvoBWnr5v9dYYwjMgXd7XRbCoonxiPHvc hMTQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Q1kFunwd; 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 nd7si12755714ejc.747.2021.05.10.03.57.33; Mon, 10 May 2021 03:57:57 -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=Q1kFunwd; 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 S233706AbhEJKzI (ORCPT + 99 others); Mon, 10 May 2021 06:55:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:59640 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232700AbhEJKod (ORCPT ); Mon, 10 May 2021 06:44:33 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id ED72661942; Mon, 10 May 2021 10:33:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620642814; bh=a+QuohTaC6glZ6PvIP3fOdTsEtYTwlL06hIldNmB0Uk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q1kFunwdsDhIGjxNE0ki9NDtX0r9eQenBVvdRCYmBsaEIy6sZNPUL3yEdnOgS7Pz+ TbILj72Z+fa0YaDSvpo6SkzyDyV4kyCz6PU3Y5SIIELYn2PjwSxbHtQLNTiGSFT4Z0 3lqi9kXWvH0GnyVYSr5FUGzLjJg18XUsVTwGY860= 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.10 045/299] btrfs: fix metadata extent leak after failure to create subvolume Date: Mon, 10 May 2021 12:17:22 +0200 Message-Id: <20210510102006.356602277@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210510102004.821838356@linuxfoundation.org> References: <20210510102004.821838356@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 @@ -678,8 +678,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); @@ -688,8 +686,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_get_new_fs_root(fs_info, objectid, anon_dev);