Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp106049yba; Mon, 20 May 2019 05:49:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqyMA7R1VZWfslcuejmEikBsUujUPKRNb0eOsuaR+sOAwX3AoqSKvodKEdhYZviAFiWyC4I5 X-Received: by 2002:a63:e048:: with SMTP id n8mr75265353pgj.41.1558356558542; Mon, 20 May 2019 05:49:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558356558; cv=none; d=google.com; s=arc-20160816; b=ylwcc+xUEC4AJ9S7aClIwD10tKlzNSprlV7Bi0yQixKdWzcq+1cFIXr7XGQbX/2vgT 3Whdy7CRkcBUmZ0ZC/NeGUa2QMUTHsBBXO8jp52uieRtYx9RgET7VXnFsO5U7SWcupo5 ZX5bn9E/ZaOM56hPtNZ/ei8aN/ZTil/H0Mk3YJjMTNdNxVwRttqzi5C5kKVVXnwLWxEW kaWU6DeC5wfG/pZMJeMF+v6+uchvTBMSug4X75e/HDfW2n2B9j8SxhzKsSU9EaxI1yAB GbK+ce6dY5o7oTevUI4cq5Y8EbmmhowMfOrPaX9dOdUZcay4CIFzrtbVSFRkAFrQY8Bb X42Q== 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=WOl0GJmqQ9/YsXD0kHejbjuq6JrtnNNLrIYMrG0kyUY=; b=siuqb+p0WBGR/k7zbfqatvtmcGZBAuKSXLDFodvLQp0GwINrIVMfwOWYjzeBq8QovV slDSWj8hK2aGJVJjUpBcovkviTtAhqyU1jr23m20LCh3i5Hz+l1kE/l1gEgDI4kZInbY tWwZX0MYDd6IxEHlVpzfMyUFtWJsoExJ6jwD592P2ELnI+ii0hEs7zLgc9LAgQ2tuDoE zC0PFIJuqiqNSJ/Z89ApujKrp8KoIJvpFITp4QHRGpn88ZDa9JsAlhli0UVJZkZ1roMP u6DhijF7RTV62VlzmEPWFFYQ7b0PUr1gXliUe8QvHtv5uYtgoNgz1KfANwwcSndvSAFZ sLfQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kzGzR4Ip; 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 t24si18233155plr.56.2019.05.20.05.49.03; Mon, 20 May 2019 05:49:18 -0700 (PDT) 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=kzGzR4Ip; 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 S2389421AbfETMr2 (ORCPT + 99 others); Mon, 20 May 2019 08:47:28 -0400 Received: from mail.kernel.org ([198.145.29.99]:39052 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388238AbfETMYO (ORCPT ); Mon, 20 May 2019 08:24:14 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.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 9121E21479; Mon, 20 May 2019 12:24:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558355053; bh=15RPKwpw4JLzs1WOUCE36293hirvTF5FismRFcT6P5g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kzGzR4IpKFwBMby5cruhh6JcbnSfSWxj6iNq+W6ihwEvn5u+vk+0+M0EGptR1AEYb ljkvVjmMN3fr44DjRdOjhpB5BhJ0jV62//bOrs+3eoJlA1M4+/AFibRnXd95auwUxJ EIJvZdPxtNXabmLpcfYxkZQ2cyuhr7OS9NtpaSKA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Zygo Blaxell , Filipe Manana , David Sterba Subject: [PATCH 4.19 078/105] Btrfs: do not start a transaction at iterate_extent_inodes() Date: Mon, 20 May 2019 14:14:24 +0200 Message-Id: <20190520115252.656532570@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520115247.060821231@linuxfoundation.org> References: <20190520115247.060821231@linuxfoundation.org> User-Agent: quilt/0.66 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 From: Filipe Manana commit bfc61c36260ca990937539cd648ede3cd749bc10 upstream. When finding out which inodes have references on a particular extent, done by backref.c:iterate_extent_inodes(), from the BTRFS_IOC_LOGICAL_INO (both v1 and v2) ioctl and from scrub we use the transaction join API to grab a reference on the currently running transaction, since in order to give accurate results we need to inspect the delayed references of the currently running transaction. However, if there is currently no running transaction, the join operation will create a new transaction. This is inefficient as the transaction will eventually be committed, doing unnecessary IO and introducing a potential point of failure that will lead to a transaction abort due to -ENOSPC, as recently reported [1]. That's because the join, creates the transaction but does not reserve any space, so when attempting to update the root item of the root passed to btrfs_join_transaction(), during the transaction commit, we can end up failling with -ENOSPC. Users of a join operation are supposed to actually do some filesystem changes and reserve space by some means, which is not the case of iterate_extent_inodes(), it is a read-only operation for all contextes from which it is called. The reported [1] -ENOSPC failure stack trace is the following: heisenberg kernel: ------------[ cut here ]------------ heisenberg kernel: BTRFS: Transaction aborted (error -28) heisenberg kernel: WARNING: CPU: 0 PID: 7137 at fs/btrfs/root-tree.c:136 btrfs_update_root+0x22b/0x320 [btrfs] (...) heisenberg kernel: CPU: 0 PID: 7137 Comm: btrfs-transacti Not tainted 4.19.0-4-amd64 #1 Debian 4.19.28-2 heisenberg kernel: Hardware name: FUJITSU LIFEBOOK U757/FJNB2A5, BIOS Version 1.21 03/19/2018 heisenberg kernel: RIP: 0010:btrfs_update_root+0x22b/0x320 [btrfs] (...) heisenberg kernel: RSP: 0018:ffffb5448828bd40 EFLAGS: 00010286 heisenberg kernel: RAX: 0000000000000000 RBX: ffff8ed56bccef50 RCX: 0000000000000006 heisenberg kernel: RDX: 0000000000000007 RSI: 0000000000000092 RDI: ffff8ed6bda166a0 heisenberg kernel: RBP: 00000000ffffffe4 R08: 00000000000003df R09: 0000000000000007 heisenberg kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff8ed63396a078 heisenberg kernel: R13: ffff8ed092d7c800 R14: ffff8ed64f5db028 R15: ffff8ed6bd03d068 heisenberg kernel: FS: 0000000000000000(0000) GS:ffff8ed6bda00000(0000) knlGS:0000000000000000 heisenberg kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 heisenberg kernel: CR2: 00007f46f75f8000 CR3: 0000000310a0a002 CR4: 00000000003606f0 heisenberg kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 heisenberg kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 heisenberg kernel: Call Trace: heisenberg kernel: commit_fs_roots+0x166/0x1d0 [btrfs] heisenberg kernel: ? _cond_resched+0x15/0x30 heisenberg kernel: ? btrfs_run_delayed_refs+0xac/0x180 [btrfs] heisenberg kernel: btrfs_commit_transaction+0x2bd/0x870 [btrfs] heisenberg kernel: ? start_transaction+0x9d/0x3f0 [btrfs] heisenberg kernel: transaction_kthread+0x147/0x180 [btrfs] heisenberg kernel: ? btrfs_cleanup_transaction+0x530/0x530 [btrfs] heisenberg kernel: kthread+0x112/0x130 heisenberg kernel: ? kthread_bind+0x30/0x30 heisenberg kernel: ret_from_fork+0x35/0x40 heisenberg kernel: ---[ end trace 05de912e30e012d9 ]--- So fix that by using the attach API, which does not create a transaction when there is currently no running transaction. [1] https://lore.kernel.org/linux-btrfs/b2a668d7124f1d3e410367f587926f622b3f03a4.camel@scientia.net/ Reported-by: Zygo Blaxell 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/backref.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1908,13 +1908,19 @@ int iterate_extent_inodes(struct btrfs_f extent_item_objectid); if (!search_commit_root) { - trans = btrfs_join_transaction(fs_info->extent_root); - if (IS_ERR(trans)) - return PTR_ERR(trans); + trans = btrfs_attach_transaction(fs_info->extent_root); + if (IS_ERR(trans)) { + if (PTR_ERR(trans) != -ENOENT && + PTR_ERR(trans) != -EROFS) + return PTR_ERR(trans); + trans = NULL; + } + } + + if (trans) btrfs_get_tree_mod_seq(fs_info, &tree_mod_seq_elem); - } else { + else down_read(&fs_info->commit_root_sem); - } ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, tree_mod_seq_elem.seq, &refs, @@ -1947,7 +1953,7 @@ int iterate_extent_inodes(struct btrfs_f free_leaf_list(refs); out: - if (!search_commit_root) { + if (trans) { btrfs_put_tree_mod_seq(fs_info, &tree_mod_seq_elem); btrfs_end_transaction(trans); } else {