Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp17570imu; Tue, 15 Jan 2019 15:33:50 -0800 (PST) X-Google-Smtp-Source: ALg8bN6ttawHNB9muJEbwhBvCMLeNL3GIEhY1BA7HZeWtiwsbduaQsTwDWF6m4XOYT52Ezh4WNMU X-Received: by 2002:a17:902:bc3:: with SMTP id 61mr6725812plr.15.1547595230216; Tue, 15 Jan 2019 15:33:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547595230; cv=none; d=google.com; s=arc-20160816; b=S2kjZTUSlSw5R8Jzq6wMtYcBl+xuLmS9rKPsP+DN9eNrThIxfWwHHbsLWb4L0MPhQY 7ybx3gNpU0wxnarwykAfYzZFRFNClRPu2qvmMuxS1TtLovynaYkrAnggr+fXXiwVaLsO U5Rvs8jF93O8HYjEkInzLImEaGboJvPwHa0rjUZiBJ7YegPNkPLMo7uMemI2zICzbcJl 3LsBTWC39cQrkRf7tbgM9dMTlS/qoq2xNLNmeM9R4C7woGYMKSkjt+dhrGgb06Bv+xZQ zHAAtK5twAwtswaWN49YN4WIwU+P917ZbpZFsNX8VZss/N/a1lp8zYKGuwUVhpudM1s5 l8+w== 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=X4vin5vCI3B93959irlXLSjIL+bF/I3A/Pxhzf24XkM=; b=dwlkMIzsGcPrkZeq5r3ohaav3e5yrRCbPt4pMomZS+vtcMvovZAmihLPuxxwjfaya7 HAlQ/iohMQFkDiDKS3b04IGfNf9gtuXr0ZQXKIUdvtShO1s2x16+/dt4aE4jvFURsZnL p1JqLAV2D2oMNQYdOqGbNUFzCf77yF/r7PuIiUAQ0qXpIwqzqGIXqaM290PV8hmeFq/5 /KfyEO3Pew4pIpJdHibOgh5bpdpQCiSwTohwcO3E6qRk6wgLvSHv5He+RTsaUT7BrIrw Y/aGVF331InCjFeRujzNARqCVJQDmoq5+M6dKHsnfsKwC2piYaXAtcvpj8m0EWb8IXhK BJsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=sMa7M2Rm; 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 80si4885039pfz.11.2019.01.15.15.33.12; Tue, 15 Jan 2019 15:33:50 -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=sMa7M2Rm; 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 S2387882AbfAOQpz (ORCPT + 99 others); Tue, 15 Jan 2019 11:45:55 -0500 Received: from mail.kernel.org ([198.145.29.99]:35536 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387859AbfAOQpu (ORCPT ); Tue, 15 Jan 2019 11:45:50 -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 1090F20859; Tue, 15 Jan 2019 16:45:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1547570748; bh=7EinwiCHwBsQSCv4hDzw8KdoHLP5va2mqbwLxzSLmIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sMa7M2RmE8hXjc+ORe+HdcyyrTfvr33lScND/nCWEubbcYZgP4QkxrgHDAb9nuGoH 0JOcZZx5RgNSjsXxYaCFpBr/kEzvryCxzUBmwrRjZRrbSOPNYL1x3vsRV60eL2kBvx u1gnZdDUBEZCOnzheYtaQE6TYi8VO1KEfYghSJLY= 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 56/57] Btrfs: fix deadlock when enabling quotas due to concurrent snapshot creation Date: Tue, 15 Jan 2019 17:36:37 +0100 Message-Id: <20190115154914.150419825@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190115154910.734892368@linuxfoundation.org> References: <20190115154910.734892368@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 9a6f209e36500efac51528132a3e3083586eda5f upstream. If the quota enable and snapshot creation ioctls are called concurrently we can get into a deadlock where the task enabling quotas will deadlock on the fs_info->qgroup_ioctl_lock mutex because it attempts to lock it twice, or the task creating a snapshot tries to commit the transaction while the task enabling quota waits for the former task to commit the transaction while holding the mutex. The following time diagrams show how both cases happen. First scenario: CPU 0 CPU 1 btrfs_ioctl() btrfs_ioctl_quota_ctl() btrfs_quota_enable() mutex_lock(fs_info->qgroup_ioctl_lock) btrfs_start_transaction() btrfs_ioctl() btrfs_ioctl_snap_create_v2 create_snapshot() --> adds snapshot to the list pending_snapshots of the current transaction btrfs_commit_transaction() create_pending_snapshots() create_pending_snapshot() qgroup_account_snapshot() btrfs_qgroup_inherit() mutex_lock(fs_info->qgroup_ioctl_lock) --> deadlock, mutex already locked by this task at btrfs_quota_enable() Second scenario: CPU 0 CPU 1 btrfs_ioctl() btrfs_ioctl_quota_ctl() btrfs_quota_enable() mutex_lock(fs_info->qgroup_ioctl_lock) btrfs_start_transaction() btrfs_ioctl() btrfs_ioctl_snap_create_v2 create_snapshot() --> adds snapshot to the list pending_snapshots of the current transaction btrfs_commit_transaction() --> waits for task at CPU 0 to release its transaction handle btrfs_commit_transaction() --> sees another task started the transaction commit first --> releases its transaction handle --> waits for the transaction commit to be completed by the task at CPU 1 create_pending_snapshot() qgroup_account_snapshot() btrfs_qgroup_inherit() mutex_lock(fs_info->qgroup_ioctl_lock) --> deadlock, task at CPU 0 has the mutex locked but it is waiting for us to finish the transaction commit So fix this by setting the quota enabled flag in fs_info after committing the transaction at btrfs_quota_enable(). This ends up serializing quota enable and snapshot creation as if the snapshot creation happened just before the quota enable request. The quota rescan task, scheduled after committing the transaction in btrfs_quote_enable(), will do the accounting. Fixes: 6426c7ad697d ("btrfs: qgroup: Fix qgroup accounting when creating snapshot") Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/qgroup.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1013,16 +1013,22 @@ out_add_root: btrfs_abort_transaction(trans, ret); goto out_free_path; } - spin_lock(&fs_info->qgroup_lock); - fs_info->quota_root = quota_root; - set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); - spin_unlock(&fs_info->qgroup_lock); ret = btrfs_commit_transaction(trans); trans = NULL; if (ret) goto out_free_path; + /* + * Set quota enabled flag after committing the transaction, to avoid + * deadlocks on fs_info->qgroup_ioctl_lock with concurrent snapshot + * creation. + */ + spin_lock(&fs_info->qgroup_lock); + fs_info->quota_root = quota_root; + set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags); + spin_unlock(&fs_info->qgroup_lock); + ret = qgroup_rescan_init(fs_info, 0, 1); if (!ret) { qgroup_rescan_zero_tracking(fs_info);