Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3506938imu; Mon, 7 Jan 2019 04:46:24 -0800 (PST) X-Google-Smtp-Source: ALg8bN7CcZb0W1ODKuavt+FPMRUdWKNYmwuqvey2sxwr92GIPrmGTCcKOfpcMN9MARXHtk62iy9b X-Received: by 2002:a63:fb4c:: with SMTP id w12mr10921701pgj.321.1546865184790; Mon, 07 Jan 2019 04:46:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546865184; cv=none; d=google.com; s=arc-20160816; b=hVtxGwmIiOV7mpGBHejalHWLdImoQin4QtOZsZOsz11PS8EyfGP5L7zV4sDezbDGf6 M+Bi1qG9/gYdpJaeIO5E4949CfUlpC7ER/vxg/Rh4u9+m5ubzlyF/rqt7hP0DwqHbIqo OPMLQb6BPAr5s25/DHoLUAYj/VgB/MEiBhfiXO8/7s/PIONV+TgDiz7/dkYQxG7lZaQr D/bFU0UZnw5uf1xlRIexBgS5HEEqL7Kk7N0KWaxyLBTlcI8DjGi2M9XBG7i3DJHaKLWi rMB8PZyQ4qDmoSgoJBhho5eU7zsuwzYDnYrELDmYxBSxI9rbZCvIVd579f9CdYnGXnMK XyEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=7Id88NwiGor3KRBvKzGbo9SaO/4QqtiJx7sFbaDKXWA=; b=f2uwqa3seuKxCq8hVo/Hbjmyptp2z/vTckxQvw4h4lrDDlgAaqMcr42Q55H7mK1edO t4Weo79lu7nfPJO9mBrdypwTdIVib700ubz7U9dO51n3bjL8yS5laO4Yq1PArjmRUCJ6 geZNvfO9lAdtsDNeNR4pT97OOI9SZzO84lHYzUs0o442oif6npbRrYwc7CWKlzY0W4QO Yv+yk+upO5CtTinC0YVmJBrblf1DExKHwJ5uEv+odUP9Gg12eCuS4vWSK5rGKzNcZRVB Be1oeNaZu/y8mLtofUA8FHCa+KpdEevQkF4kwpLCS1rjmlUmGTJ+EK+JwhuBP+m00mpN BLGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WxXWRBj8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u22si59671485pgh.286.2019.01.07.04.46.09; Mon, 07 Jan 2019 04:46:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WxXWRBj8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728764AbfAGMo2 (ORCPT + 99 others); Mon, 7 Jan 2019 07:44:28 -0500 Received: from mail.kernel.org ([198.145.29.99]:32924 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727324AbfAGMo0 (ORCPT ); Mon, 7 Jan 2019 07:44:26 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 84D9D2177B; Mon, 7 Jan 2019 12:44:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546865065; bh=VLu3TFiQ0KNuDmcWLcBjOfsecM8mEB22snLI2mFtYeM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WxXWRBj8qRHrAUWhXJf+M6aflW5gaFoE/kKwR/97eTiFPoX7aWHK6Y1TaA4mUyrvz AGVCme88K9ZeXegj/H4ppvA9cnoqWRDCmZH7HN/9EUfFXgNZvUoLbzpIkE4mRctLcC sixdK4R67eQo41uTNdaodAlV5HbUx1A2NKxAAzqg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Filipe Manana , David Sterba Subject: [PATCH 4.20 098/145] Btrfs: send, fix race with transaction commits that create snapshots Date: Mon, 7 Jan 2019 13:32:15 +0100 Message-Id: <20190107104450.053435515@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107104437.308206189@linuxfoundation.org> References: <20190107104437.308206189@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ From: Filipe Manana commit be6821f82c3cc36e026f5afd10249988852b35ea upstream. If we create a snapshot of a snapshot currently being used by a send operation, we can end up with send failing unexpectedly (returning -ENOENT error to user space for example). The following diagram shows how this happens. CPU 1 CPU2 CPU3 btrfs_ioctl_send() (...) create_snapshot() -> creates snapshot of a root used by the send task btrfs_commit_transaction() create_pending_snapshot() __get_inode_info() btrfs_search_slot() btrfs_search_slot_get_root() down_read commit_root_sem get reference on eb of the commit root -> eb with bytenr == X up_read commit_root_sem btrfs_cow_block(root node) btrfs_free_tree_block() -> creates delayed ref to free the extent btrfs_run_delayed_refs() -> runs the delayed ref, adds extent to fs_info->pinned_extents btrfs_finish_extent_commit() unpin_extent_range() -> marks extent as free in the free space cache transaction commit finishes btrfs_start_transaction() (...) btrfs_cow_block() btrfs_alloc_tree_block() btrfs_reserve_extent() -> allocates extent at bytenr == X btrfs_init_new_buffer(bytenr X) btrfs_find_create_tree_block() alloc_extent_buffer(bytenr X) find_extent_buffer(bytenr X) -> returns existing eb, which the send task got (...) -> modifies content of the eb with bytenr == X -> uses an eb that now belongs to some other tree and no more matches the commit root of the snapshot, resuts will be unpredictable The consequences of this race can be various, and can lead to searches in the commit root performed by the send task failing unexpectedly (unable to find inode items, returning -ENOENT to user space, for example) or not failing because an inode item with the same number was added to the tree that reused the metadata extent, in which case send can behave incorrectly in the worst case or just fail later for some reason. Fix this by performing a copy of the commit root's extent buffer when doing a search in the context of a send operation. CC: stable@vger.kernel.org # 4.4.x: 1fc28d8e2e9: Btrfs: move get root out of btrfs_search_slot to a helper CC: stable@vger.kernel.org # 4.4.x: f9ddfd0592a: Btrfs: remove unused check of skip_locking CC: stable@vger.kernel.org # 4.4.x Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ctree.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2584,14 +2584,27 @@ static struct extent_buffer *btrfs_searc root_lock = BTRFS_READ_LOCK; if (p->search_commit_root) { - /* The commit roots are read only so we always do read locks */ - if (p->need_commit_sem) + /* + * The commit roots are read only so we always do read locks, + * and we always must hold the commit_root_sem when doing + * searches on them, the only exception is send where we don't + * want to block transaction commits for a long time, so + * we need to clone the commit root in order to avoid races + * with transaction commits that create a snapshot of one of + * the roots used by a send operation. + */ + if (p->need_commit_sem) { down_read(&fs_info->commit_root_sem); - b = root->commit_root; - extent_buffer_get(b); - level = btrfs_header_level(b); - if (p->need_commit_sem) + b = btrfs_clone_extent_buffer(root->commit_root); up_read(&fs_info->commit_root_sem); + if (!b) + return ERR_PTR(-ENOMEM); + + } else { + b = root->commit_root; + extent_buffer_get(b); + } + level = btrfs_header_level(b); /* * Ensure that all callers have set skip_locking when * p->search_commit_root = 1. @@ -2717,6 +2730,10 @@ int btrfs_search_slot(struct btrfs_trans again: prev_cmp = -1; b = btrfs_search_slot_get_root(root, p, write_lock_level); + if (IS_ERR(b)) { + ret = PTR_ERR(b); + goto done; + } while (b) { level = btrfs_header_level(b);