From patchwork Thu Nov 24 08:12:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 9444941 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 11E54606DB for ; Thu, 24 Nov 2016 08:13:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0622426E39 for ; Thu, 24 Nov 2016 08:13:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EDBC62711E; Thu, 24 Nov 2016 08:13:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 95B522766D for ; Thu, 24 Nov 2016 08:13:43 +0000 (UTC) Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id uAO8DRBo031659 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 24 Nov 2016 08:13:28 GMT Received: from oss.oracle.com (oss-old-reserved.oracle.com [137.254.22.2]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id uAO8DOUT016325 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 24 Nov 2016 08:13:24 GMT Received: from localhost ([127.0.0.1] helo=lb-oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1c9p9o-0004Ru-A1; Thu, 24 Nov 2016 00:13:24 -0800 Received: from userv0021.oracle.com ([156.151.31.71]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1c9p9Q-0004PY-2e for ocfs2-devel@oss.oracle.com; Thu, 24 Nov 2016 00:13:00 -0800 Received: from aserp1020.oracle.com (aserp1020.oracle.com [141.146.126.67]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id uAO8CxEt015567 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 24 Nov 2016 08:12:59 GMT Received: from userp2040.oracle.com (userp2040.oracle.com [156.151.31.90]) by aserp1020.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id uAO8CwRA031000 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 24 Nov 2016 08:12:59 GMT Received: from pps.filterd (userp2040.oracle.com [127.0.0.1]) by userp2040.oracle.com (8.16.0.17/8.16.0.17) with SMTP id uAO8BYE0009266 for ; Thu, 24 Nov 2016 08:12:58 GMT Authentication-Results: oracle.com; spf=pass smtp.mailfrom=jack@suse.cz Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by userp2040.oracle.com with ESMTP id 26w6jk2xsb-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 24 Nov 2016 08:12:58 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 1C1C0AC34; Thu, 24 Nov 2016 08:12:55 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 795A71E2F91; Thu, 24 Nov 2016 09:12:53 +0100 (CET) From: Jan Kara To: Date: Thu, 24 Nov 2016 09:12:37 +0100 Message-Id: <1479975162-24060-3-git-send-email-jack@suse.cz> X-Mailer: git-send-email 2.6.6 In-Reply-To: <1479975162-24060-1-git-send-email-jack@suse.cz> References: <1479975162-24060-1-git-send-email-jack@suse.cz> X-PDR: PASS X-ServerName: mx2.suse.de X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 ip4:137.65.0.0/16 ip4:151.155.28.0/17 ip4:149.44.0.0/16 ip4:147.2.0.0/16 ip4:164.99.0.0/16 ip4:130.57.0.0/16 ip4:192.31.114.0/24 ip4:195.135.221.0/24 ip4:195.135.220.0/24 ip4:69.7.179.0/24 ip4:150.215.214.0/24 include:mailcontrol.com ~all X-Proofpoint-Virus-Version: vendor=nai engine=5800 definitions=8358 signatures=670744 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1611240142 Cc: Jan Kara , Al Viro , ocfs2-devel@oss.oracle.com Subject: [Ocfs2-devel] [PATCH 2/7] quota: Hold s_umount in exclusive mode when enabling / disabling quotas 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: userv0021.oracle.com [156.151.31.71] X-Virus-Scanned: ClamAV using ClamSMTP Currently we hold s_umount semaphore only in shared mode when enabling or disabling quotas and use dqonoff_mutex for serializing quota state changes on a filesystem and also quota state changes with other places depending on current quota state. Using dedicated mutex for this causes possible deadlocks during filesystem freezing (see following commit for details) so we transition to using s_umount semaphore for the necessary synchronization whose lock ordering is properly handled by the filesystem freezing code. As a start grab s_umount in exclusive mode when enabling / disabling quotas. Signed-off-by: Jan Kara --- fs/quota/dquot.c | 11 +++++++++++ fs/quota/quota.c | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 1bfac28b7e7d..047afb966420 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2107,6 +2107,10 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags) struct quota_info *dqopt = sb_dqopt(sb); struct inode *toputinode[MAXQUOTAS]; + /* s_umount should be held in exclusive mode */ + if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount))) + up_read(&sb->s_umount); + /* Cannot turn off usage accounting without turning off limits, or * suspend quotas and simultaneously turn quotas off. */ if ((flags & DQUOT_USAGE_ENABLED && !(flags & DQUOT_LIMITS_ENABLED)) @@ -2371,6 +2375,10 @@ int dquot_resume(struct super_block *sb, int type) int ret = 0, cnt; unsigned int flags; + /* s_umount should be held in exclusive mode */ + if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount))) + up_read(&sb->s_umount); + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; @@ -2430,6 +2438,9 @@ int dquot_enable(struct inode *inode, int type, int format_id, /* Just unsuspend quotas? */ BUG_ON(flags & DQUOT_SUSPENDED); + /* s_umount should be held in exclusive mode */ + if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount))) + up_read(&sb->s_umount); if (!flags) return 0; diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 2d445425aad7..790c61abc663 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -790,6 +790,12 @@ static int quotactl_cmd_write(int cmd) return 1; } +/* Return true if quotactl command is manipulating quota on/off state */ +static bool quotactl_cmd_onoff(int cmd) +{ + return (cmd == Q_QUOTAON) || (cmd == Q_QUOTAOFF); +} + #endif /* CONFIG_BLOCK */ /* @@ -809,7 +815,9 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) putname(tmp); if (IS_ERR(bdev)) return ERR_CAST(bdev); - if (quotactl_cmd_write(cmd)) + if (quotactl_cmd_onoff(cmd)) + sb = get_super_exclusive_thawed(bdev); + else if (quotactl_cmd_write(cmd)) sb = get_super_thawed(bdev); else sb = get_super(bdev); @@ -872,7 +880,10 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, ret = do_quotactl(sb, type, cmds, id, addr, pathp); - drop_super(sb); + if (!quotactl_cmd_onoff(cmds)) + drop_super(sb); + else + drop_super_exclusive(sb); out: if (pathp && !IS_ERR(pathp)) path_put(pathp);