Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2978315imu; Sun, 9 Dec 2018 14:09:11 -0800 (PST) X-Google-Smtp-Source: AFSGD/WK+6oGv7L5PEgNaU5tnLoaOO23D4NdA4vhbeEpmyWv1i5WmoLc1q5CxJ6xVi3YQRwqbV9Q X-Received: by 2002:a65:6491:: with SMTP id e17mr8730930pgv.418.1544393351355; Sun, 09 Dec 2018 14:09:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544393351; cv=none; d=google.com; s=arc-20160816; b=KSuribcYtmAfSH6LtNPAkuV0If/nrIVx7I4Yglfpc7Zo2Kq+reDhZgo+44K9UuG+8C Ikp2WhfEl0ytXkj2VFz+DcMKuTYu3SOBvSKj2ewkPz7ZoMxGhBRN1XX1F8ObTd01/zzu n+ROHf836jyFoJJebTbb8OcEbu2lf0suQXxPfJFBEhlxKewZhPDJLIEmn+OCprljVo+X 0tTrmjRXIBJrbxvA5Uea9M8BZpPW69qZUxHZmeVkms08SSaPVD45mSlUPfzZdSHKqMXz /c02ynVW/29DKfC0MRVogDfHOCrpPLNwISLzay5pD4f9d5jX2udmEmQF21aFZc8SCLKv YJTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=uUzN5yLmDFxW07N6gyDLO6e8KVihyusZSQpE7qeBdag=; b=vT6HOIgOtKsGmDrd9EjntsoI7Up5hC1k4r15M/Cbfg7lCvCAl9Y2mXD9Aummiuic3/ gPOs5VRaOqfVoU32MOqb82BeZ0zS3CS6BHpZfu/WHXZRrtk3ek5keN3vsTRm88k8+sM0 CXYfwJ1W9y4iD/ZKjWlqINim0IEpyoUQyBwaVodYslirAJOFeSzyiGxtVbubXqw7zveS iK9NtJztC7stmZxmYGwWLJWeUVr0C3FF6IL6omtI5XA93mSRHKPh394451Fm8rYtMaPT AnT+QflsTzkw/SVn06PFkXI8F/SZjMckhUafrTZbzVhiGS05wzAAwlz11eDtYaLtBLQr 7CZQ== ARC-Authentication-Results: i=1; mx.google.com; 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 i96si8698671plb.188.2018.12.09.14.08.56; Sun, 09 Dec 2018 14:09:11 -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; 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 S1727905AbeLIWHc (ORCPT + 99 others); Sun, 9 Dec 2018 17:07:32 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:37218 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726859AbeLIWH2 (ORCPT ); Sun, 9 Dec 2018 17:07:28 -0500 Received: from pub.yeoldevic.com ([81.174.156.145] helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gW73I-0002iZ-JT; Sun, 09 Dec 2018 21:55:52 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gW72c-0003M0-CB; Sun, 09 Dec 2018 21:55:10 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "David Sterba" , "Omar Sandoval" , "Josef Bacik" Date: Sun, 09 Dec 2018 21:50:33 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 110/328] Btrfs: fix btrfs_write_inode vs delayed iput deadlock In-Reply-To: X-SA-Exim-Connect-IP: 81.174.156.145 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.62-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Josef Bacik commit 3c4276936f6fbe52884b4ea4e6cc120b890a0f9f upstream. We recently ran into the following deadlock involving btrfs_write_inode(): [ +0.005066] __schedule+0x38e/0x8c0 [ +0.007144] schedule+0x36/0x80 [ +0.006447] bit_wait+0x11/0x60 [ +0.006446] __wait_on_bit+0xbe/0x110 [ +0.007487] ? bit_wait_io+0x60/0x60 [ +0.007319] __inode_wait_for_writeback+0x96/0xc0 [ +0.009568] ? autoremove_wake_function+0x40/0x40 [ +0.009565] inode_wait_for_writeback+0x21/0x30 [ +0.009224] evict+0xb0/0x190 [ +0.006099] iput+0x1a8/0x210 [ +0.006103] btrfs_run_delayed_iputs+0x73/0xc0 [ +0.009047] btrfs_commit_transaction+0x799/0x8c0 [ +0.009567] btrfs_write_inode+0x81/0xb0 [ +0.008008] __writeback_single_inode+0x267/0x320 [ +0.009569] writeback_sb_inodes+0x25b/0x4e0 [ +0.008702] wb_writeback+0x102/0x2d0 [ +0.007487] wb_workfn+0xa4/0x310 [ +0.006794] ? wb_workfn+0xa4/0x310 [ +0.007143] process_one_work+0x150/0x410 [ +0.008179] worker_thread+0x6d/0x520 [ +0.007490] kthread+0x12c/0x160 [ +0.006620] ? put_pwq_unlocked+0x80/0x80 [ +0.008185] ? kthread_park+0xa0/0xa0 [ +0.007484] ? do_syscall_64+0x53/0x150 [ +0.007837] ret_from_fork+0x29/0x40 Writeback calls: btrfs_write_inode btrfs_commit_transaction btrfs_run_delayed_iputs If iput() is called on that same inode, evict() will wait for writeback forever. btrfs_write_inode() was originally added way back in 4730a4bc5bf3 ("btrfs_dirty_inode") to support O_SYNC writes. However, ->write_inode() hasn't been used for O_SYNC since 148f948ba877 ("vfs: Introduce new helpers for syncing after writing to O_SYNC file or IS_SYNC inode"), so btrfs_write_inode() is actually unnecessary (and leads to a bunch of unnecessary commits). Get rid of it, which also gets rid of the deadlock. Signed-off-by: Josef Bacik [Omar: new commit message] Signed-off-by: Omar Sandoval Signed-off-by: David Sterba [bwh: Backported to 3.16: deleted function is slightly different] Signed-off-by: Ben Hutchings --- --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5542,31 +5542,6 @@ err: return ret; } -int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) -{ - struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_trans_handle *trans; - int ret = 0; - bool nolock = false; - - if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags)) - return 0; - - if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(inode)) - nolock = true; - - if (wbc->sync_mode == WB_SYNC_ALL) { - if (nolock) - trans = btrfs_join_transaction_nolock(root); - else - trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) - return PTR_ERR(trans); - ret = btrfs_commit_transaction(trans, root); - } - return ret; -} - /* * This is somewhat expensive, updating the tree every time the * inode changes. But, it is most likely to find the inode in cache. --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1852,7 +1852,6 @@ static const struct super_operations btr .sync_fs = btrfs_sync_fs, .show_options = btrfs_show_options, .show_devname = btrfs_show_devname, - .write_inode = btrfs_write_inode, .alloc_inode = btrfs_alloc_inode, .destroy_inode = btrfs_destroy_inode, .statfs = btrfs_statfs,