From patchwork Wed Oct 24 10:18:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Kinsbursky X-Patchwork-Id: 1637411 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id C389B3FCF7 for ; Wed, 24 Oct 2012 10:16:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933621Ab2JXKQc (ORCPT ); Wed, 24 Oct 2012 06:16:32 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:34345 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933517Ab2JXKQc (ORCPT ); Wed, 24 Oct 2012 06:16:32 -0400 Received: from localhost.localdomain ([10.30.21.131]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id q9OAGAgx024935; Wed, 24 Oct 2012 14:16:10 +0400 (MSK) Subject: [PATCH] lockd: fix races in per-net NSM client handling To: Trond.Myklebust@netapp.com From: Stanislav Kinsbursky Cc: bfields@fieldses.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, devel@openvz.org Date: Wed, 24 Oct 2012 14:18:10 +0400 Message-ID: <20121024101713.22494.75940.stgit@localhost.localdomain> In-Reply-To: <87fw55hsue.fsf@spindle.srvr.nix> References: <87fw55hsue.fsf@spindle.srvr.nix> User-Agent: StGit/0.16 MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org This patch fixes two problems: 1) Removes races on NSM creation. 2) Fixes silly misprint on NSM client destruction (usage counter was checked for non-zero value instead of zero). Signed-off-by: Stanislav Kinsbursky --- fs/lockd/mon.c | 35 +++++++++++++++++++++++------------ 1 files changed, 23 insertions(+), 12 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e4fb3ba..e3e59f6 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -85,30 +85,41 @@ static struct rpc_clnt *nsm_create(struct net *net) return rpc_create(&args); } -static struct rpc_clnt *nsm_client_get(struct net *net) +static struct rpc_clnt *nsm_get_client(struct net *net) { - static DEFINE_MUTEX(nsm_create_mutex); - struct rpc_clnt *clnt; + struct rpc_clnt *clnt = NULL; struct lockd_net *ln = net_generic(net, lockd_net_id); spin_lock(&ln->nsm_clnt_lock); if (ln->nsm_users) { ln->nsm_users++; clnt = ln->nsm_clnt; - spin_unlock(&ln->nsm_clnt_lock); - goto out; } spin_unlock(&ln->nsm_clnt_lock); + return clnt; +} + +static struct rpc_clnt *nsm_client_get(struct net *net) +{ + static DEFINE_MUTEX(nsm_create_mutex); + struct rpc_clnt *clnt; + struct lockd_net *ln = net_generic(net, lockd_net_id); + + clnt = nsm_get_client(net); + if (clnt) + return clnt; mutex_lock(&nsm_create_mutex); - clnt = nsm_create(net); - if (!IS_ERR(clnt)) { - ln->nsm_clnt = clnt; - smp_wmb(); - ln->nsm_users = 1; + clnt = nsm_get_client(net); + if (clnt == NULL) { + clnt = nsm_create(net); + if (!IS_ERR(clnt)) { + ln->nsm_clnt = clnt; + smp_wmb(); + ln->nsm_users = 1; + } } mutex_unlock(&nsm_create_mutex); -out: return clnt; } @@ -120,7 +131,7 @@ static void nsm_client_put(struct net *net) spin_lock(&ln->nsm_clnt_lock); if (ln->nsm_users) { - if (--ln->nsm_users) + if (--ln->nsm_users == 0) ln->nsm_clnt = NULL; shutdown = !ln->nsm_users; }