Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2504375pxj; Mon, 10 May 2021 04:43:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxY63snGwYX1MK6SpdS0rl0Mm42E1hcil6i447/DT40t4dH1JmnIRtutWYI1Yxu6WrBz4Ww X-Received: by 2002:a17:906:80d6:: with SMTP id a22mr24472639ejx.159.1620647012785; Mon, 10 May 2021 04:43:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620647012; cv=none; d=google.com; s=arc-20160816; b=pMVN9W314A5pTODtg8nml8PvIHJdwU0G2XNWIhcKjWULoPtPqGDPG5pTrH9YtKGbWs SZp0WF5jytTiFX15PZppMWIrl6O1TD5XjnZUPpRgf4qOck/5ZZGfXaaU5dWn/jcpXMZn 5lSPNRZ7lSopXE5vvBh/DZ1HOvqJ47rhhCNj56p6pob0YDTLG4ZJ1DUzybFbzGf3trxN CBuhAbbkERR0VI6xKt41rpiq8GibjubHfEkhpv3cjh849nIc8QmzK9pNOWzRRa+xjRm6 CJ40tcg/hl9cfcU3RZzZ7SebDOcQXixyw6txzQgkTM4VZ2XT8hHt8y/1awP2kO8B+pFG HEZA== 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=DjBkBKdV3nJhOov1unooN1vyRWa54SGMHHmrtrk3//4=; b=WfCU1kOL0eyqIT608EycStSWbW3Qghgyl+6Jff/s2E5FVLyKVpBAx0IrqZvW82pX4f zrWrYVFo1B3q+oYbbRrB+6CV5/K+L0zreVagHKFVba5l0/dr6UQ+7jltOxxywjWXugQF gc2jf4RFyFqIWEdelMFmxaQp0co/0Xvb61MwwOmadYhG+wjKnilArrkMxm1FXCKnr3/d VNNxN2X/VJv2c2Drtwk+Wa1QxGsmrLeM/0PZn61x1RsZW7SJ1EG/o2te1bN2+AaWyx5y YxIe5/D4oesd+6WE1CJBtopiUYKFFFRGyXvwvjsjWPkvk5oVsOGy2Cmo8NllgfqNm3Qq tH1Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="bxRKGk/O"; 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 u12si12516777ejj.721.2021.05.10.04.43.09; Mon, 10 May 2021 04:43:32 -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="bxRKGk/O"; 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 S241781AbhEJLix (ORCPT + 99 others); Mon, 10 May 2021 07:38:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:53030 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234495AbhEJK4e (ORCPT ); Mon, 10 May 2021 06:56:34 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 14FFB61929; Mon, 10 May 2021 10:46:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620643585; bh=FQZHMoOkpHH6mnSEK5GzmQpWDpqT+zEUd4P0/cUcliY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bxRKGk/OZ55nSQhrejjrjicoz287cDtHSpOY72EpPRHSRO5DH6rn1ik15UfFqAN16 c4mhsONxsk/RQnewB882nMhj89KD8KiRWtpR4yOESa4f3OB9bxTj8SJBWW/zW6b8xG tSC/p1seMyO2pV2iFZDS7aps+YoSGSYWnGc+FODU= 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.11 057/342] btrfs: fix metadata extent leak after failure to create subvolume Date: Mon, 10 May 2021 12:17:27 +0200 Message-Id: <20210510102012.008918391@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210510102010.096403571@linuxfoundation.org> References: <20210510102010.096403571@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 @@ -690,8 +690,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); @@ -700,8 +698,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);