From patchwork Mon Jun 30 15:49:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 4451661 Return-Path: X-Original-To: patchwork-linux-nfs@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 4368B9F358 for ; Mon, 30 Jun 2014 15:52:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2F23F2021F for ; Mon, 30 Jun 2014 15:51:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 31FC720225 for ; Mon, 30 Jun 2014 15:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754744AbaF3Pv5 (ORCPT ); Mon, 30 Jun 2014 11:51:57 -0400 Received: from mail-qc0-f170.google.com ([209.85.216.170]:39684 "EHLO mail-qc0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754260AbaF3Pv4 (ORCPT ); Mon, 30 Jun 2014 11:51:56 -0400 Received: by mail-qc0-f170.google.com with SMTP id l6so7362690qcy.29 for ; Mon, 30 Jun 2014 08:51:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=mau58LLXRaNGnDmioPS/JDCYtzIJLCwQ/CkKQ61Vseg=; b=nHfU0kq2XeVs2/OkPseMcAlLaKvhhRrqyVp1rMMCqJ7a88pM8oD9Jda4YupgZOr2Wj vNisjoLbq0qbM6Lw4rrBFef5SE1tYxzhwFL10QuLv1wnXbliv8uxg9AF0zwUkXCQZnry l0Ybi/mE+YF2W4Al5tNB7JCKNhpCCaq0Umu4QnmTvAvvN7VzNbtTiCXQTkXgClpVwuqc rz0Iu4PaPTAzyhgc+h+951PLS4f2jFe20wMzZIBcVRyytYqTZoK0tpTzm3NXNVygFtrH qQ07ZG8peFYJnMP2b8qiOfBLvhF+JLDzEhyW7EIgXyqSPBjmPX9cjl1emPjB77sYGhfm AYnA== X-Gm-Message-State: ALoCoQmUWMEnHwekmgsSomHy+4dAzqvGyLB+VLKbFazIVo32naBZEYkw94FRKjPwk+oE2dT4pCQe X-Received: by 10.224.223.135 with SMTP id ik7mr63830711qab.26.1404143515935; Mon, 30 Jun 2014 08:51:55 -0700 (PDT) Received: from tlielax.poochiereds.net ([2001:470:8:d63:3a60:77ff:fe93:a95d]) by mx.google.com with ESMTPSA id m1sm32584105qaz.27.2014.06.30.08.51.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 30 Jun 2014 08:51:55 -0700 (PDT) From: Jeff Layton To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org, Trond Myklebust Subject: [PATCH v3 059/114] nfsd: Add reference counting to state owners Date: Mon, 30 Jun 2014 11:49:28 -0400 Message-Id: <1404143423-24381-60-git-send-email-jlayton@primarydata.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1404143423-24381-1-git-send-email-jlayton@primarydata.com> References: <1404143423-24381-1-git-send-email-jlayton@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 From: Trond Myklebust The way stateowners are managed today is somewhat awkward. They need to be explicitly destroyed, even though the stateids reference them. This will be particularly problematic when we remove the client_mutex. We may create a new stateowner and attempt to open a file or set a lock, and have that fail. In the meantime, another RPC may come in that uses that same stateowner and succeed. We can't have the first task tearing down the stateowner in that situation. To fix this, we need to change how stateowners are tracked altogether. Refcount them and only destroy them once all stateids that reference them have been destroyed. This patch starts by adding the refcounting necessary to do that. Signed-off-by: Trond Myklebust Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 43 +++++++++++++++++++++++++++++-------------- fs/nfsd/state.h | 3 +++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0f30716c9093..d260bb3145ed 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -72,6 +72,7 @@ static u64 current_sessionid = 1; /* forward declarations */ static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); static void nfs4_free_generic_stateid(struct nfs4_stid *stid); +static void nfs4_put_stateowner(struct nfs4_stateowner *sop); /* Locking: */ @@ -925,16 +926,10 @@ static void unhash_lockowner(struct nfs4_lockowner *lo) } } -static void nfs4_free_lockowner(struct nfs4_lockowner *lo) -{ - kfree(lo->lo_owner.so_owner.data); - kmem_cache_free(lockowner_slab, lo); -} - static void release_lockowner(struct nfs4_lockowner *lo) { unhash_lockowner(lo); - nfs4_free_lockowner(lo); + nfs4_put_stateowner(&lo->lo_owner); } static void release_lockowner_if_empty(struct nfs4_lockowner *lo) @@ -1004,18 +999,12 @@ static void release_last_closed_stateid(struct nfs4_openowner *oo) } } -static void nfs4_free_openowner(struct nfs4_openowner *oo) -{ - kfree(oo->oo_owner.so_owner.data); - kmem_cache_free(openowner_slab, oo); -} - static void release_openowner(struct nfs4_openowner *oo) { unhash_openowner(oo); list_del(&oo->oo_close_lru); release_last_closed_stateid(oo); - nfs4_free_openowner(oo); + nfs4_put_stateowner(&oo->oo_owner); } static inline int @@ -2947,9 +2936,17 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj INIT_LIST_HEAD(&sop->so_stateids); sop->so_client = clp; init_nfs4_replay(&sop->so_replay); + atomic_set(&sop->so_count, 1); return sop; } +static void nfs4_put_stateowner(struct nfs4_stateowner *sop) +{ + if (!atomic_dec_and_test(&sop->so_count)) + return; + sop->so_free(sop); +} + static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval) { struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); @@ -2958,6 +2955,14 @@ static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, u list_add(&oo->oo_perclient, &clp->cl_openowners); } +static void nfs4_free_openowner(struct nfs4_stateowner *so) +{ + struct nfs4_openowner *oo = openowner(so); + + kfree(oo->oo_owner.so_owner.data); + kmem_cache_free(openowner_slab, oo); +} + static struct nfs4_openowner * alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open, struct nfsd4_compound_state *cstate) @@ -2968,6 +2973,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open, oo = alloc_stateowner(openowner_slab, &open->op_owner, clp); if (!oo) return NULL; + oo->oo_owner.so_free = nfs4_free_openowner; oo->oo_owner.so_is_open_owner = 1; oo->oo_owner.so_seqid = open->op_seqid; oo->oo_flags = NFS4_OO_NEW; @@ -4677,6 +4683,14 @@ find_lockowner_str(clientid_t *clid, struct xdr_netobj *owner, return NULL; } +static void nfs4_free_lockowner(struct nfs4_stateowner *sop) +{ + struct nfs4_lockowner *lo = lockowner(sop); + + kfree(lo->lo_owner.so_owner.data); + kmem_cache_free(lockowner_slab, lo); +} + /* * Alloc a lock owner structure. * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has @@ -4697,6 +4711,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str /* It is the openowner seqid that will be incremented in encode in the * case of new lockowners; so increment the lock seqid manually: */ lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1; + lo->lo_owner.so_free = nfs4_free_lockowner; list_add(&lo->lo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]); return lo; } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 7188dcd45ef7..eba7283a2613 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -340,10 +340,13 @@ struct nfs4_stateowner { struct nfs4_client * so_client; /* after increment in ENCODE_SEQID_OP_TAIL, represents the next * sequence id expected from the client: */ + atomic_t so_count; u32 so_seqid; struct xdr_netobj so_owner; /* open owner name */ struct nfs4_replay so_replay; bool so_is_open_owner; + + void (*so_free)(struct nfs4_stateowner *); }; struct nfs4_openowner {