From patchwork Thu Feb 20 16:55:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 3688931 Return-Path: X-Original-To: patchwork-ocfs2-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 92B739F35F for ; Thu, 20 Feb 2014 16:56:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C1C1F2017E for ; Thu, 20 Feb 2014 16:56:12 +0000 (UTC) Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A57B920179 for ; Thu, 20 Feb 2014 16:56:11 +0000 (UTC) Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s1KGtxon013291 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 20 Feb 2014 16:55:59 GMT Received: from oss.oracle.com (oss-external.oracle.com [137.254.96.51]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s1KGtrhw000901 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 20 Feb 2014 16:55:54 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1WGWuf-000356-SK; Thu, 20 Feb 2014 08:55:53 -0800 Received: from ucsinet21.oracle.com ([156.151.31.93]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1WGWuP-00034k-30 for ocfs2-devel@oss.oracle.com; Thu, 20 Feb 2014 08:55:37 -0800 Received: from aserp1030.oracle.com (aserp1030.oracle.com [141.146.126.68]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s1KGtZfM005048 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 20 Feb 2014 16:55:36 GMT Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by aserp1030.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s1KGtXpm015583 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Thu, 20 Feb 2014 16:55:35 GMT Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 67EF1AC86; Thu, 20 Feb 2014 16:55:33 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 30C7980D20; Thu, 20 Feb 2014 17:55:32 +0100 (CET) From: Jan Kara To: linux-fsdevel@vger.kernel.org Date: Thu, 20 Feb 2014 17:55:29 +0100 Message-Id: <1392915329-3464-1-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.8.1.4 X-Flow-Control-Info: class=Pass-to-MM reputation=ipRisk-All ip=195.135.220.15 ct-class=T2 ct-vol1=0 ct-vol2=4 ct-vol3=3 ct-risk=59 ct-spam1=75 ct-spam2=44 ct-bulk=37 rcpts=1 size=2123 X-SPF-Info: NONE::cantor2.suse.de X-Sendmail-CM-Score: 0.00% X-Sendmail-CM-Analysis: v=2.1 cv=UMXkQkvy c=1 sm=1 tr=0 a=uEuDQZVrWKuLCe7byFjfVg==:117 a=uEuDQZVrWKuLCe7byFjfVg==:17 a=PnhkTVicK0kA:10 a=GUDuU-C7sAQA:10 a=IVfO9EmPVWVKIKx8nyQA:9 X-Sendmail-CT-Classification: not spam X-Sendmail-CT-RefID: str=0001.0A090202.53063387.00AA:SCFSTAT18040053, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 Cc: Mark Fasheh , Jan Kara , ocfs2-devel@oss.oracle.com Subject: [Ocfs2-devel] [PATCH] quota: Fix race between dqput() and dquot_scan_active() X-BeenThere: ocfs2-devel@oss.oracle.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ocfs2-devel-bounces@oss.oracle.com Errors-To: ocfs2-devel-bounces@oss.oracle.com X-Source-IP: acsinet22.oracle.com [141.146.126.238] X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently last dqput() can race with dquot_scan_active() causing it to call callback for an already deactivated dquot. The race is as follows: CPU1 CPU2 dqput() spin_lock(&dq_list_lock); if (atomic_read(&dquot->dq_count) > 1) { - not taken if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { spin_unlock(&dq_list_lock); ->release_dquot(dquot); if (atomic_read(&dquot->dq_count) > 1) - not taken dquot_scan_active() spin_lock(&dq_list_lock); if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) - not taken atomic_inc(&dquot->dq_count); spin_unlock(&dq_list_lock); - proceeds to release dquot ret = fn(dquot, priv); - called for inactive dquot Fix the problem by making sure possible ->release_dquot() is finished by the time we call the callback and new calls to it will notice reference dquot_scan_active() has taken and bail out. Signed-off-by: Jan Kara --- fs/quota/dquot.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) This is the last patch needed to make ocfs2 quotas rock solid in my testing. I will carry it in my tree and push it to Linus soon. diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 831d49a4111f..cfc8dcc16043 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -581,9 +581,17 @@ int dquot_scan_active(struct super_block *sb, dqstats_inc(DQST_LOOKUPS); dqput(old_dquot); old_dquot = dquot; - ret = fn(dquot, priv); - if (ret < 0) - goto out; + /* + * ->release_dquot() can be racing with us. Our reference + * protects us from new calls to it so just wait for any + * outstanding call and recheck the DQ_ACTIVE_B after that. + */ + wait_on_dquot(dquot); + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + ret = fn(dquot, priv); + if (ret < 0) + goto out; + } spin_lock(&dq_list_lock); /* We are safe to continue now because our dquot could not * be moved out of the inuse list while we hold the reference */